Example #1
0
    def __get_migrations(self):
        instance = MigrateMgr.instance()

        installed = instance.last_installed_migration_id()

        status = 'installed'
        items = instance.sort_clients()
        items.sort()

        migrations = []
        for (id, migration) in items:
            migrations.append((migration, status))
            if installed == id:
                status = 'new'
        return migrations
Example #2
0
def main():
    logging.basicConfig(format='%(message)s')

    opt = optparse.OptionParser()
    opt.add_option('--update-to', '-t', default=None)
    opt.add_option('--update-new', '-u', action="store_true", default=False)
    opt.add_option('--cherry-pick-update', '-p', default=None)
    opt.add_option('--cherry-pick-downgrade', '-d', default=None)
    opt.add_option('--testdb', default=None)
    options, arguments = opt.parse_args()

    if options.testdb:
        Configuration.config_file = '/etc/trac/cqde.test.ini'
        conf.refresh()

    exec "from multiproject.core.migrations import *"
    param_was_given = True
    mgr = MigrateMgr.instance()
    if options.update_new:
        mgr.update_new()
    elif options.update_to:
        mgr.update_to(options.update_to)
    elif options.cherry_pick_update:
        mgr.cherry_pick(options.cherry_pick_update, True)
    elif options.cherry_pick_downgrade:
        mgr.cherry_pick(options.cherry_pick_downgrade, False)
    else:
        param_was_given = False
    mgr.show_status()

    if not param_was_given:
        print "\n\nTo install migrations, run:"
        print "    python update.py --update-new"
        print "        - Runs all new migration. Shorthand: -u"
        print "\nOther options are:"
        print "    --update-to=MIGRATION, -t=MIGRATION"
        print "        - Runs all migrations up or down to the given name"
        print "    --cherry-pick-update=MIGRATION, -p=MIGRATION"
        print "        - Tries to update one, single migration. Dangerous!"
        print "    --cherry-pick-downgrade=MIGRATION, -d=MIGRATION"
        print "        - Tries to downgrade one, single migration. Dangerous!"
        print "\nTo show just status"
        print "    python update.py"
Example #3
0
def main():
    logging.basicConfig(format='%(message)s')

    opt = optparse.OptionParser()
    opt.add_option('--update-to', '-t', default=None)
    opt.add_option('--update-new', '-u', action="store_true", default=False)
    opt.add_option('--cherry-pick-update', '-p',default=None)
    opt.add_option('--cherry-pick-downgrade', '-d', default=None)
    opt.add_option('--testdb', default=None)
    options, arguments = opt.parse_args()

    if options.testdb:
        Configuration.config_file = '/etc/trac/cqde.test.ini'
        conf.refresh()

    exec "from multiproject.core.migrations import *"
    param_was_given = True
    mgr = MigrateMgr.instance()
    if options.update_new:
        mgr.update_new()
    elif options.update_to:
        mgr.update_to(options.update_to)
    elif options.cherry_pick_update:
        mgr.cherry_pick(options.cherry_pick_update, True)
    elif options.cherry_pick_downgrade:
        mgr.cherry_pick(options.cherry_pick_downgrade, False)
    else:
        param_was_given = False
    mgr.show_status()

    if not param_was_given:
        print "\n\nTo install migrations, run:"
        print "    python update.py --update-new"
        print "        - Runs all new migration. Shorthand: -u"
        print "\nOther options are:"
        print "    --update-to=MIGRATION, -t=MIGRATION"
        print "        - Runs all migrations up or down to the given name"
        print "    --cherry-pick-update=MIGRATION, -p=MIGRATION"
        print "        - Tries to update one, single migration. Dangerous!"
        print "    --cherry-pick-downgrade=MIGRATION, -d=MIGRATION"
        print "        - Tries to downgrade one, single migration. Dangerous!"
        print "\nTo show just status"
        print "    python update.py"
    def downgrade(self):
        if not self.applied():
            print "Migration {0} not applied yet".format(__file__).rjust(12)
            return False

        queries = [
            """
        UPDATE action
        SET action_string = 'ADMIN_CREATE_USER'
        WHERE action_string = 'USER_CREATE'
        """
        ]

        return self.manager.db_downgrade(queries)

    def applied(self):
        """
        Check if column exists or not
        :returns: True if exists, otherwise False
        """
        count = 0
        with admin_query(cursors.DictCursor) as cursor:
            cursor.execute('SELECT COUNT(action_id) AS count FROM action WHERE action_string = "ADMIN_CREATE_USER"')
            count = int(cursor.fetchone()["count"])

        return count == 0


MigrateMgr.instance().add(UserPermissionRename())
        queries = []
        query = """
        DELETE FROM %s.event_dim
        WHERE action_name = '%s'
        """

        for action in self.actions.keys():
            queries.append(query % (conf.db_analytical_schema_name, action))

        return self.manager.db_downgrade(queries)

    def applied(self):
        """
        Check if column exists or not
        :returns: True if exists, otherwise False
        """
        action_names = []

        with analytical_query() as cursor:
            cursor.execute('SELECT action_name FROM %s.event_dim' %
                           conf.db_analytical_schema_name)
            action_names = [row[0] for row in cursor]

        # Check if all actions can be found from event_dim
        return not all([(action not in action_names)
                        for action in self.actions.keys()])


MigrateMgr.instance().add(ProjectWatchEventTypes())
        return self.manager.db_upgrade(queries)

    def downgrade(self):
        if not self.applied():
            print "Migration {0} not applied yet".format(__file__).rjust(12)
            return False

        queries = ["""
            ALTER TABLE trac_admin.user DROP deputies
        """]

        return self.manager.db_downgrade(queries)

    def applied(self):

        with admin_query() as cursor:
            cursor.execute('''
                SELECT COLUMN_NAME FROM information_schema.COLUMNS 
                    WHERE TABLE_SCHEMA = 'trac_admin' 
                    AND TABLE_NAME = 'user' 
                    AND COLUMN_NAME = 'deputies'
            ''')
            row_num = int(cursor.rowcount)
            if row_num == 1:
                return True

        return False

MigrateMgr.instance().add(AddDeputiesForUsers())
Example #7
0
                   AND time < 2147483648;
                """ % {
                    'identifier': MySQLdb.escape_string(identifier)
                }
                cursor.execute(query)
                # Above select always returns a row, unless an exception is thrown
                count = cursor.fetchone()[0]
                if count and count != 0:
                    was_applied = False
                    break

        return was_applied

    def _get_project_identifier_rows(self):
        """
        Queries trac environment names from ``trac_admin`` database

        :returns: All trac environment names from ``trac_environment`` table
        """
        # TODO: instead of identifier_rows, return project_schema_names as a list
        rows = []

        with admin_query() as cursor:
            cursor.execute("SELECT identifier FROM `trac_environment`;")
            rows = cursor.fetchall()

        return rows


MigrateMgr.instance().add(WikiStartTimeToUTimeStamp())
Example #8
0
        """
        Remove the global_announcements table from trac_admin database.
        """
        if not self.applied():
            return False

        queries = ['DROP TABLE `global_announcements`']
        return self.manager.db_downgrade(queries)

    def applied(self):
        """
        Check if the global_announcements table already exist in trac_admin database.

        :returns: True if the table is there, False if it's not.
        """
        conf = Configuration.instance()

        with admin_query() as cursor:
            cursor.execute('''
                SELECT table_name FROM information_schema.tables
                WHERE table_schema = '{0}'
                AND table_name = 'global_announcements'
            '''.format(conf.db_admin_schema_name))
            if cursor.rowcount != 1:
                return False

        return True


MigrateMgr.instance().add(CreateGlobalAnnouncementsTable())
                `tag_key` MEDIUMINT(8) UNSIGNED NOT NULL,
                PRIMARY KEY (`project_key`, `tag_key`),
                INDEX `new_fk_constraint2` (`tag_key`),
                CONSTRAINT `new_fk_constraint` FOREIGN KEY (`project_key`) REFERENCES `projects` (`project_id`) ON UPDATE CASCADE ON DELETE CASCADE,
                CONSTRAINT `new_fk_constraint2` FOREIGN KEY (`tag_key`) REFERENCES `tags` (`tag_id`) ON UPDATE CASCADE ON DELETE CASCADE
            )
            COLLATE='utf8_bin'
            ENGINE=InnoDB
            ROW_FORMAT=DEFAULT
            '''
        ]

        return self.manager.db_downgrade(queries)

    def applied(self):
        """
        Check if column exists or not
        :returns: True if exists, otherwise False
        """
        conf = Configuration.instance()
        with admin_query() as cursor:
            cursor.execute('''
                SELECT table_name FROM information_schema.tables
                WHERE table_schema = '{0}'
                AND table_name = 'tags'
            '''.format(conf.db_admin_schema_name))
            return cursor.rowcount != 1


MigrateMgr.instance().add(DropProjectTags())
                for row in cursor:
                    group_key = row['group_key']
                    for new_perm in perm_map[meta_perm]:
                        query = 'REPLACE INTO `group_permission` SET `group_key`=%s, `permission_key`=%s' % \
                            (group_key, new_perm)
                        queries.append(query)

        # delete metaperms
        for meta_perm in meta_perms:
            queries.append(
                "DELETE FROM `action` WHERE `action_string` = '%s'" %
                meta_perm)
        for id in meta_perm_ids:
            queries.append(
                "DELETE FROM group_permission WHERE permission_key = %s" % id)

        queries.append('SET foreign_key_checks = 1')
        return self.manager.db_upgrade(queries)

    def downgrade(self):
        # cannot be downgraded, but should work without them
        pass

    def applied(self):
        with admin_query(cursors.DictCursor) as cursor:
            cursor.execute("SELECT * FROM action WHERE action_string='VIEW'")
            return cursor.fetchone() is None


MigrateMgr.instance().add(RemoveMetaPerms())
Example #11
0
        self.description = "Change authentication method datatype from enum to varchar"

    def upgrade(self):
        if self.applied():
            print "            Migration already applied"
            return True

        procedures = [
""" ALTER TABLE authentication CHANGE method method VARCHAR(32) COLLATE utf8_bin NOT NULL
"""
]

        return self.manager.db_upgrade(procedures)

    def downgrade(self):
        if not self.applied():
            print "            Migration 20110906120000_authentication_method_datatype.py not applied"
            return False

        procedures = [
""" ALTER TABLE authentication CHANGE method method enum('LDAP','Ovi','Forum','LocalDB') COLLATE utf8_bin NOT NULL
"""
]

        return self.manager.db_downgrade(procedures)

    def applied(self):
        return self.manager.db_applied("DESC authentication", 1, 1, 'varchar(32)')

MigrateMgr.instance().add(AuthenticationMethodDatatype())
    def applied(self):
        """
        Check if the ssh key related tables already exist in trac_admin database.

        :returns: True if the tables are there, False if they're not.
        """
        conf = Configuration.instance()

        with admin_query() as cursor:
            cursor.execute('''
                SELECT table_name FROM information_schema.tables
                WHERE table_schema = '{0}'
                AND table_name = 'ssh_keys'
            '''.format(conf.db_admin_schema_name))
            if cursor.rowcount != 1:
                return False

            cursor.execute('''
                SELECT table_name FROM information_schema.tables
                WHERE table_schema = '{0}'
                AND table_name = 'ssh_key_update'
            '''.format(conf.db_admin_schema_name))
            if cursor.rowcount != 1:
                return False

        return True


MigrateMgr.instance().add(CreateSshKeysTables())
        with admin_query() as cursor:
            cursor.execute(
                """
                SELECT table_name FROM information_schema.tables
                WHERE table_schema = '{0}'
                AND table_name = 'ssh_keys'
            """.format(
                    conf.db_admin_schema_name
                )
            )
            if cursor.rowcount != 1:
                return False

            cursor.execute(
                """
                SELECT table_name FROM information_schema.tables
                WHERE table_schema = '{0}'
                AND table_name = 'ssh_key_update'
            """.format(
                    conf.db_admin_schema_name
                )
            )
            if cursor.rowcount != 1:
                return False

        return True


MigrateMgr.instance().add(CreateSshKeysTables())

        return self.manager.db_upgrade(queries)

    def downgrade(self):
        if not self.applied():
            print "Migration {0} not applied yet".format(__file__).rjust(12)
            return False

        queries = ["""
        DELETE FROM %s.context_dim
        WHERE context = "Admin Project VCM");
        """ % conf.db_analytical_schema_name]

        return self.manager.db_downgrade(queries)

    def applied(self):

        with analytical_query() as cursor:
            cursor.execute('''
                SELECT COUNT(*) AS count FROM %s.context_dim
                WHERE context = 'Admin Project VCM'
            ''' % conf.db_analytical_schema_name)
            row = cursor.fetchone()
            if row[0] == 1:
                return True

        return False

MigrateMgr.instance().add(AddContextDimForRepositoryManager())
            CREATE INDEX download_status_idx ON `project_download`
            (project_id, status, download_path(255));
            ''']

        return self.manager.db_upgrade(queries)

    def downgrade(self):
        if not self.applied():
            print ""
            return True

        queries = ['DROP INDEX download_status_idx ON `project_download`']
        return self.manager.db_downgrade(queries)

    def applied(self):
        with admin_query() as cursor:
            cursor.execute('''
                SELECT COUNT(*) FROM information_schema.statistics
                WHERE table_schema = %s
                AND table_name = 'project_download'
                AND index_name = 'download_status_idx';
            ''', conf.db_admin_schema_name)
            row = cursor.fetchone()
            if row[0] == 0:
                return False

        return True


MigrateMgr.instance().add(DownloadStatusIndex())
        queries = []
        query = """
        DELETE FROM %s.event_dim
        WHERE action_name = '%s'
        """

        for action, crud, context in self.actions:
            queries.append(query % (conf.db_analytical_schema_name, action))

        return self.manager.db_downgrade(queries)

    def applied(self):
        """
        Check if column exists or not
        :returns: True if exists, otherwise False
        """
        action_names = []

        with analytical_query() as cursor:
            cursor.execute('SELECT action_name FROM %s.event_dim' %
                           conf.db_analytical_schema_name)
            action_names = [row[0] for row in cursor]

        # Check if all actions can be found from event_dim
        return not all([(action not in action_names)
                        for action, crud, context in self.actions])


MigrateMgr.instance().add(FilesCopyEvent())
        CREATE TABLE %s.data_queue (
            `id` INT(10) NOT NULL AUTO_INCREMENT,
            `data` LONGTEXT NULL,
            PRIMARY KEY (`id`)
        )
        """ % conf.db_analytical_schema_name
        ]
        return self.manager.db_upgrade(queries)

    def downgrade(self):
        if not self.applied():
            print "Migration {0} not applied yet".format(__file__).rjust(12)
            return False

        queries = [
            """
        DROP TABLE %s.data_queue
        """ % conf.db_analytical_schema_name
        ]
        return self.manager.db_downgrade(queries)

    def applied(self):
        with analytical_query() as cursor:
            cursor.execute('SHOW TABLES LIKE "data_queue"')
            for row in cursor:
                return True
        return False


MigrateMgr.instance().add(AnalyticsJSON())
Example #18
0
            '''
        ]

        return self.manager.db_upgrade(queries)

    def downgrade(self):
        if not self.applied():
            print ""
            return True

        queries = ['DROP INDEX download_status_idx ON `project_download`']
        return self.manager.db_downgrade(queries)

    def applied(self):
        with admin_query() as cursor:
            cursor.execute(
                '''
                SELECT COUNT(*) FROM information_schema.statistics
                WHERE table_schema = %s
                AND table_name = 'project_download'
                AND index_name = 'download_status_idx';
            ''', conf.db_admin_schema_name)
            row = cursor.fetchone()
            if row[0] == 0:
                return False

        return True


MigrateMgr.instance().add(DownloadStatusIndex())
Example #19
0

        return self.manager.db_upgrade(queries)

    def downgrade(self):
        if not self.applied():
            print "Migration {0} not applied yet".format(__file__).rjust(12)
            return False

        queries = ["""
        DELETE FROM %s.context_dim
        WHERE context IN ("Project permissions","Home permissions");
        """ % conf.db_analytical_schema_name]

        return self.manager.db_downgrade(queries)

    def applied(self):

        with analytical_query() as cursor:
            cursor.execute('''
                SELECT COUNT(*) AS count FROM %s.context_dim
                WHERE (context IN ('Project permissions','Home permissions','Admin Users','Admin Groups', 'Group templates'))
            ''' % conf.db_analytical_schema_name)
            row = cursor.fetchone()
            if row[0] == 6:
                return True

        return False

MigrateMgr.instance().add(AddContextDimForPermission())
                                           WHERE method = '{method}')
           """.format(organization_id=local_organization_id, method=LOCAL)]
        return self.manager.db_upgrade(queries)

    def downgrade(self):
        if not self.applied():
            print "Migration was not applied."
            return True
        else:
            print "Migration cannot be downgraded."
            self._was_downgraded = True
            return True

    def applied(self):
        """
        Check if column exists or not
        :returns: True if exists, otherwise False
        """
        if self._was_downgraded:
            return False
        with admin_query() as cursor:
            cursor.execute('''
                SELECT count(*) FROM user
                WHERE user_id NOT IN (SELECT user_key FROM user_organization)
                AND authentication_key IN (SELECT id FROM authentication WHERE method = '{0}')
            '''.format(LOCAL))
            row = cursor.fetchone()
            return row[0] == 0

MigrateMgr.instance().add(MissingOrganizations())
        if not self.applied():
            print "Migration {0} not applied yet".format(__file__).rjust(12)
            return False

        queries = []
        query = """
        DELETE FROM %s.event_dim
        WHERE action_name = '%s'
        """

        for action in self.actions.keys():
            queries.append(query % (conf.db_analytical_schema_name, action))

        return self.manager.db_downgrade(queries)

    def applied(self):
        """
        Check if column exists or not
        :returns: True if exists, otherwise False
        """
        action_names = []

        with analytical_query() as cursor:
            cursor.execute('SELECT action_name FROM %s.event_dim' % conf.db_analytical_schema_name)
            action_names = [row[0] for row in cursor]

        # Check if all actions can be found from event_dim
        return not all([(action not in action_names) for action in self.actions.keys()])

MigrateMgr.instance().add(ProjectWatchEventTypes())
            with admin_query(cursors.DictCursor) as cursor:
                cursor.execute('SELECT group_key FROM group_permission WHERE permission_key=%s',
                    meta_perm_id)
                for row in cursor:
                    group_key = row['group_key']
                    for new_perm in perm_map[meta_perm]:
                        query = 'REPLACE INTO `group_permission` SET `group_key`=%s, `permission_key`=%s' % \
                            (group_key, new_perm)
                        queries.append(query)

        # delete metaperms
        for meta_perm in meta_perms:
            queries.append("DELETE FROM `action` WHERE `action_string` = '%s'" % meta_perm)
        for id in meta_perm_ids:
            queries.append("DELETE FROM group_permission WHERE permission_key = %s" % id)

        queries.append('SET foreign_key_checks = 1')
        return self.manager.db_upgrade(queries)

    def downgrade(self):
        # cannot be downgraded, but should work without them
        pass

    def applied(self):
        with admin_query(cursors.DictCursor) as cursor:
            cursor.execute("SELECT * FROM action WHERE action_string='VIEW'")
            return cursor.fetchone() is None


MigrateMgr.instance().add(RemoveMetaPerms())
                  FROM `%(identifier)s`.`wiki`
                 WHERE (name = 'WikiStart' OR name = 'Downloads') AND version = 1
                   AND time < 2147483648;
                """ % { 'identifier' : MySQLdb.escape_string(identifier)}
                cursor.execute(query)
                # Above select always returns a row, unless an exception is thrown
                count = cursor.fetchone()[0]
                if count and count != 0:
                    was_applied = False
                    break

        return was_applied

    def _get_project_identifier_rows(self):
        """
        Queries trac environment names from ``trac_admin`` database

        :returns: All trac environment names from ``trac_environment`` table
        """
        # TODO: instead of identifier_rows, return project_schema_names as a list
        rows = []

        with admin_query() as cursor:
            cursor.execute("SELECT identifier FROM `trac_environment`;")
            rows = cursor.fetchall()

        return rows


MigrateMgr.instance().add(WikiStartTimeToUTimeStamp())
Example #24
0
                    ticket_changes = ticketchanges,
                    wiki_changes = wikichanges,
                    scm_changes = scmchanges,
                    discussion_changes = discussionchanges,
                    attachment_changes = attachmentchanges,
                    last_update = NOW(),
                    project_description = projectdescription;
            END IF;
            END
        '''
        ]

        return self.manager.db_downgrade(queries)

    def applied(self):
        """
        Checks from database if the the procedure exists
        """
        conf = Configuration.instance()
        with admin_query() as cursor:
            cursor.execute('''
                SHOW PROCEDURE STATUS
                WHERE
                    Name = 'addactivityforproject' AND
                    Db = '{0}'
            '''.format(conf.db_admin_schema_name))
            return cursor.rowcount == 0


MigrateMgr.instance().add(NukeActivityProcedure())
        """
        if not self.applied():
            return False

        queries = ['''
        ALTER TABLE `global_announcements`
        ADD COLUMN `icon_id` int(10) unsigned DEFAULT NULL
        AFTER `topic_id`
        ''']
        return self.manager.db_downgrade(queries)

    def applied(self):
        """
        Check if migration is already applied or not
        :returns: True if migrated, otherwise False
        """
        # Test if icon_id column still exists: Exception = migration already applied
        with admin_query() as cursor:
            try:
                cursor.execute('SELECT icon_id FROM global_announcements')
            except Exception:
                return True

        return False


MigrateMgr.instance().add(DropGlobalAnnouncementIcon())


        SET expires = (NOW() + INTERVAL 3 MONTH)
        WHERE LOWER(auth.method) = 'localdb'
        """]

        return self.manager.db_upgrade(queries)

    def downgrade(self):
        if not self.applied():
            print "Migration {0} not applied yet".format(__file__).rjust(12)
            return False

        queries = [
            "ALTER TABLE user DROP COLUMN expires",
            "ALTER TABLE user DROP COLUMN author_id"
        ]

        return self.manager.db_downgrade(queries)

    def applied(self):
        """
        Check if column exists or not
        :returns: True if exists, otherwise False
        """
        with admin_query(cursors.DictCursor) as cursor:
            cursor.execute('DESC user')
        return 'expires' in [row['Field'] for row in cursor]

MigrateMgr.instance().add(UserExpiresField())


Example #27
0
        """
        ]

        return self.manager.db_upgrade(queries)

    def downgrade(self):
        if not self.applied():
            print "Migration {0} not applied yet".format(__file__).rjust(12)
            return False

        queries = [
            """
        ALTER TABLE projects
        DROP COLUMN public
        """
        ]

        return self.manager.db_downgrade(queries)

    def applied(self):
        """
        Check if column exists or not
        :returns: True if exists, otherwise False
        """
        with admin_query(cursors.DictCursor) as cursor:
            cursor.execute('DESC projects')
        return 'public' in [row['Field'] for row in cursor]


MigrateMgr.instance().add(AddPublicToProjects())
        Runs the upgrade queries
        """
        if self.applied():
            return

        queries = ['ALTER TABLE user DROP COLUMN `insider`']
        return self.manager.db_upgrade(queries)

    def downgrade(self):
        """
        Runs the downgrade queries
        """
        queries = ['ALTER TABLE `user` ADD COLUMN `insider` tinyint(1) NOT NULL DEFAULT 0 AFTER `SHA1_PW`']
        return self.manager.db_upgrade(queries)

    def applied(self):
        """
        Check if migration is already applied
        :return: True if already applied, otherwise False
        """
        with admin_query() as cursor:
            try:
                cursor.execute('SELECT insider FROM user')
            # Failure means no column
            except Exception:
                return True
        return False


MigrateMgr.instance().add(DropInsiderColumn())
            CONSTRAINT `user_fk` FOREIGN KEY (`uploader_id`) REFERENCES `user` (`user_id`) ON UPDATE CASCADE ON DELETE CASCADE
        ) DEFAULT CHARSET=utf8 COLLATE='utf8_bin' ENGINE=InnoDB;
        ''']

        return self.manager.db_upgrade(queries)

    def downgrade(self):
        if not self.applied():
            print "project_download table is not in database"
            return True

        queries = [
            'DROP TABLE `project_download`',
            ]
        return self.manager.db_downgrade(queries)

    def applied(self):
        with admin_query() as cursor:
            cursor.execute('''
                SELECT table_name FROM information_schema.tables
                WHERE table_schema = %s
                AND table_name = 'project_download'
            ''', conf.db_admin_schema_name)
            if cursor.rowcount != 1:
                return False

        return True


MigrateMgr.instance().add(CreateProjectDownloadTable())
    def upgrade(self):
        if self.applied():
            return
        queries = []
        for new, old in self.renames:
            # delete incase someone has added the new permission name to database (eg. while testing)
            queries.append(
                "DELETE FROM `action` WHERE `action_string` = '%s'" % new)
            queries.append(
                "UPDATE `action` SET `action_string`='%s' WHERE `action_string`='%s'"
                % (new, old))

        # delete permission
        queries.append(
            "DELETE FROM `action` WHERE `action_string` = 'LIST_ALL_PROJECTS'")
        return self.manager.db_upgrade(queries)

    def downgrade(self):
        queries = []
        for old, new in self.renames:
            # delete incase someone has added the new permission name to database (eg. while testing)
            queries.append(
                "DELETE FROM `action` WHERE `action_string` = '%s'" % new)
            queries.append(
                "UPDATE `action` SET `action_string`='%s' WHERE `action_string`='%s'"
                % (new, old))
        return self.manager.db_upgrade(queries)


MigrateMgr.instance().add(RenamePerms())
Example #31
0
        Runs the downgrade queries
        """
        queries = [
            '''
        CREATE PROCEDURE `get_organization_id`(organization_name VARCHAR(128))
        BEGIN
            SELECT organization_id FROM organization
            WHERE organization.organization_name = organization_name;
        END
        '''
        ]

        return self.manager.db_upgrade(queries)

    def applied(self):
        """
        Check if migration is already applied
        :return: True if already applied, otherwise False
        """
        with admin_query() as cursor:
            cursor.execute('''
                SHOW PROCEDURE STATUS
                WHERE
                    Name = 'get_organization_id' AND
                    Db = '{0}'
            '''.format(conf.db_admin_schema_name))
            return cursor.rowcount == 0


MigrateMgr.instance().add(DropGetOrgProcedure())
        self.description = self.__doc__
        self.pretend_to_be_not_applied = False

    def applied(self):
        with admin_query(cursors.DictCursor) as cursor:
            cursor.execute("SELECT * FROM action WHERE action_string='SUMMARY_VIEW'")
            return cursor.fetchone() is None

    def upgrade(self):
        if self.applied():
            return
        queries = []
        for new, old in self.renames:
            # delete incase someone has added the new permission name to database (eg. while testing)
            queries.append("DELETE FROM `action` WHERE `action_string` = '%s'" % new)
            queries.append("UPDATE `action` SET `action_string`='%s' WHERE `action_string`='%s'" % (new, old))

        # delete permission
        queries.append("DELETE FROM `action` WHERE `action_string` = 'LIST_ALL_PROJECTS'")
        return self.manager.db_upgrade(queries)

    def downgrade(self):
        queries = []
        for old, new in self.renames:
            # delete incase someone has added the new permission name to database (eg. while testing)
            queries.append("DELETE FROM `action` WHERE `action_string` = '%s'" % new)
            queries.append("UPDATE `action` SET `action_string`='%s' WHERE `action_string`='%s'" % (new, old))
        return self.manager.db_upgrade(queries)

MigrateMgr.instance().add(RenamePerms())
    def downgrade(self):
        print "Error: This migration cannot be really downgraded, but it should not be an issue"
        self._pretend_not_applied = True
        return True

    def applied(self):
        """
        Check if column exists or not
        :returns: True if exists, otherwise False
        """
        if self._pretend_not_applied:
            return False

        count = 0
        auth_store = CQDEAuthenticationStore.instance()
        id = auth_store.get_authentication_id(auth_store.LOCAL)
        with admin_query() as cursor:
            cursor.execute("""
            SELECT COUNT(*) AS count
              FROM `user`
             WHERE SHA1_PW <> 'invalidNonLocalUserPwHash'
               AND authentication_key <> %s """, (id,))
            count = int(cursor.fetchone()[0])

        return count == 0

MigrateMgr.instance().add(NonLocalUsersPasswordHashInvalidating())


        ALTER TABLE projects
        ADD COLUMN public tinyint(1) NOT NULL DEFAULT 0 AFTER trac_environment_key
        """]

        return self.manager.db_upgrade(queries)

    def downgrade(self):
        if not self.applied():
            print "Migration {0} not applied yet".format(__file__).rjust(12)
            return False

        queries = ["""
        ALTER TABLE projects
        DROP COLUMN public
        """]

        return self.manager.db_downgrade(queries)

    def applied(self):
        """
        Check if column exists or not
        :returns: True if exists, otherwise False
        """
        with admin_query(cursors.DictCursor) as cursor:
            cursor.execute('DESC projects')
        return 'public' in [row['Field'] for row in cursor]

MigrateMgr.instance().add(AddPublicToProjects())


        if self.applied():
            return

        queries = ['ALTER TABLE user DROP COLUMN `insider`']
        return self.manager.db_upgrade(queries)

    def downgrade(self):
        """
        Runs the downgrade queries
        """
        queries = [
            'ALTER TABLE `user` ADD COLUMN `insider` tinyint(1) NOT NULL DEFAULT 0 AFTER `SHA1_PW`'
        ]
        return self.manager.db_upgrade(queries)

    def applied(self):
        """
        Check if migration is already applied
        :return: True if already applied, otherwise False
        """
        with admin_query() as cursor:
            try:
                cursor.execute('SELECT insider FROM user')
            # Failure means no column
            except Exception:
                return True
        return False


MigrateMgr.instance().add(DropInsiderColumn())
                SET project_key = projectid,
                    ticket_changes = ticketchanges,
                    wiki_changes = wikichanges,
                    scm_changes = scmchanges,
                    discussion_changes = discussionchanges,
                    attachment_changes = attachmentchanges,
                    last_update = NOW(),
                    project_description = projectdescription;
            END IF;
            END
        ''']

        return self.manager.db_downgrade(queries)

    def applied(self):
        """
        Checks from database if the the procedure exists
        """
        conf = Configuration.instance()
        with admin_query() as cursor:
            cursor.execute('''
                SHOW PROCEDURE STATUS
                WHERE
                    Name = 'addactivityforproject' AND
                    Db = '{0}'
            '''.format(conf.db_admin_schema_name))
            return cursor.rowcount == 0


MigrateMgr.instance().add(NukeActivityProcedure())
        CREATE PROCEDURE `get_organization_id`(organization_name VARCHAR(128))
        BEGIN
            SELECT organization_id FROM organization
            WHERE organization.organization_name = organization_name;
        END
        """
        ]

        return self.manager.db_upgrade(queries)

    def applied(self):
        """
        Check if migration is already applied
        :return: True if already applied, otherwise False
        """
        with admin_query() as cursor:
            cursor.execute(
                """
                SHOW PROCEDURE STATUS
                WHERE
                    Name = 'get_organization_id' AND
                    Db = '{0}'
            """.format(
                    conf.db_admin_schema_name
                )
            )
            return cursor.rowcount == 0


MigrateMgr.instance().add(DropGetOrgProcedure())
Example #38
0
        SET expires = (NOW() + INTERVAL 3 MONTH)
        WHERE LOWER(auth.method) = 'localdb'
        """
        ]

        return self.manager.db_upgrade(queries)

    def downgrade(self):
        if not self.applied():
            print "Migration {0} not applied yet".format(__file__).rjust(12)
            return False

        queries = [
            "ALTER TABLE user DROP COLUMN expires",
            "ALTER TABLE user DROP COLUMN author_id"
        ]

        return self.manager.db_downgrade(queries)

    def applied(self):
        """
        Check if column exists or not
        :returns: True if exists, otherwise False
        """
        with admin_query(cursors.DictCursor) as cursor:
            cursor.execute('DESC user')
        return 'expires' in [row['Field'] for row in cursor]


MigrateMgr.instance().add(UserExpiresField())
        ]
        return self.manager.db_upgrade(queries)

    def downgrade(self):
        if not self.applied():
            print "Migration was not applied."
            return True
        else:
            print "Migration cannot be downgraded."
            self._was_downgraded = True
            return True

    def applied(self):
        """
        Check if column exists or not
        :returns: True if exists, otherwise False
        """
        if self._was_downgraded:
            return False
        with admin_query() as cursor:
            cursor.execute('''
                SELECT count(*) FROM user
                WHERE user_id NOT IN (SELECT user_key FROM user_organization)
                AND authentication_key IN (SELECT id FROM authentication WHERE method = '{0}')
            '''.format(LOCAL))
            row = cursor.fetchone()
            return row[0] == 0


MigrateMgr.instance().add(MissingOrganizations())
        return self.manager.db_upgrade(queries)

    def downgrade(self):
        if not self.applied():
            print "Migration {0} not applied yet".format(__file__).rjust(12)
            return False

        queries = [
            "DROP TABLE message_flag",
            "DROP TABLE message",
            "DROP TABLE message_group_recipient",
            "DROP TABLE message_group",
        ]

        return self.manager.db_downgrade(queries)

    def applied(self):
        """
        Check if column exists or not
        :returns: True if exists, otherwise False
        """
        with admin_query(cursors.DictCursor) as cursor:
            try:
                cursor.execute('DESC message')
            except:
                return False
        return True


MigrateMgr.instance().add(MessageTables())
        """
        ]

        return self.manager.db_upgrade(queries)

    def downgrade(self):
        if not self.applied():
            print "Migration {0} not applied yet".format(__file__).rjust(12)
            return False

        queries = [
            """
        ALTER TABLE user
        DROP COLUMN created
        """
        ]

        return self.manager.db_downgrade(queries)

    def applied(self):
        """
        Check if column exists or not
        :returns: True if exists, otherwise False
        """
        with admin_query(cursors.DictCursor) as cursor:
            cursor.execute('DESC user')
        return 'created' in [row['Field'] for row in cursor]


MigrateMgr.instance().add(UserCreationField())
        if not self.applied():
            print "Migration {0} not applied yet".format(__file__).rjust(12)
            return False

        queries = [
            """
        UPDATE action
        SET action_string = 'ADMIN_CREATE_USER'
        WHERE action_string = 'USER_CREATE'
        """
        ]

        return self.manager.db_downgrade(queries)

    def applied(self):
        """
        Check if column exists or not
        :returns: True if exists, otherwise False
        """
        count = 0
        with admin_query(cursors.DictCursor) as cursor:
            cursor.execute(
                'SELECT COUNT(action_id) AS count FROM action WHERE action_string = "ADMIN_CREATE_USER"'
            )
            count = int(cursor.fetchone()['count'])

        return count == 0


MigrateMgr.instance().add(UserPermissionRename())
            return False

        queries = []
        query = """
        DELETE FROM %s.event_dim
        WHERE action_name = '%s'
        """

        for  action, crud, context  in self.actions:
            queries.append(query % (conf.db_analytical_schema_name, action))

        return self.manager.db_downgrade(queries)

    def applied(self):
        """
        Check if column exists or not
        :returns: True if exists, otherwise False
        """
        action_names = []

        with analytical_query() as cursor:
            cursor.execute('SELECT action_name FROM %s.event_dim' % conf.db_analytical_schema_name)
            action_names = [row[0] for row in cursor]

        # Check if all actions can be found from event_dim
        return not all([(action not in action_names) for  action, crud, context in self.actions])

MigrateMgr.instance().add(FilesCopyEvent())


            SELECT group_template_id INTO template_key FROM group_template
            WHERE group_template_name = template_name;

            INSERT INTO group_template_permission VALUES(template_key, permission_key);

            COMMIT;

            END
        '''
        ]

        return self.manager.db_downgrade(queries)

    def applied(self):
        """
        Checks from database if the the procedure exists
        """
        conf = Configuration.instance()
        with admin_query() as cursor:
            cursor.execute('''
                SHOW PROCEDURE STATUS
                WHERE
                    Name = 'create_group_from_template' AND
                    Db = '{0}'
            '''.format(conf.db_admin_schema_name))
            return cursor.rowcount == 0


MigrateMgr.instance().add(NukeGroupTemplates())
        """
        if not self.applied():
            return False

        queries = [
            'DROP TABLE `global_announcements`'
        ]
        return self.manager.db_downgrade(queries)

    def applied(self):
        """
        Check if the global_announcements table already exist in trac_admin database.

        :returns: True if the table is there, False if it's not.
        """
        conf = Configuration.instance()

        with admin_query() as cursor:
            cursor.execute('''
                SELECT table_name FROM information_schema.tables
                WHERE table_schema = '{0}'
                AND table_name = 'global_announcements'
            '''.format(conf.db_admin_schema_name))
            if cursor.rowcount != 1:
                return False

        return True


MigrateMgr.instance().add(CreateGlobalAnnouncementsTable())
    def downgrade(self):
        print "Error: This migration cannot be really downgraded, but it should not be an issue"
        self._pretend_not_applied = True
        return True

    def applied(self):
        """
        Check if column exists or not
        :returns: True if exists, otherwise False
        """
        if self._pretend_not_applied:
            return False

        count = 0
        auth_store = CQDEAuthenticationStore.instance()
        id = auth_store.get_authentication_id(auth_store.LOCAL)
        with admin_query() as cursor:
            cursor.execute(
                """
            SELECT COUNT(*) AS count
              FROM `user`
             WHERE SHA1_PW <> 'invalidNonLocalUserPwHash'
               AND authentication_key <> %s """, (id, ))
            count = int(cursor.fetchone()[0])

        return count == 0


MigrateMgr.instance().add(NonLocalUsersPasswordHashInvalidating())
        # Read and parse the given icon size
        icon_width = self.icon_size["width"]
        icon_height = self.icon_size["height"]

        # Create image from data
        with open(path, "w+b") as fd:
            try:
                img = Image.open(StringIO(data))

                # Load the image right away so that we can access the image bands
                img.load()
                bands = img.split()

                # Prevent IOError: cannot write mode RGBA as BMP
                if len(bands) == 3:
                    r, g, b = bands
                    img = Image.merge("RGB", (r, g, b))
                    img.save(path)
                else:
                    # Resize first by keeping the ratio, then convert to have alpha channel and then for to given size
                    img.thumbnail((icon_width, icon_height), Image.ANTIALIAS)
                    img = img.convert("RGBA")
                    img = img.transform((icon_width, icon_height), Image.EXTENT, (0, 0, icon_width, icon_height))
                    img.save(path)

            except Exception, err:
                raise IOError("Failed to create image %s, skipping it (%s)" % (path, err))


MigrateMgr.instance().add(ProjectIcons2FS())
        """
        )

        return self.manager.db_upgrade(queries)

    def downgrade(self):
        if not self.applied():
            print "Migration {0} not applied yet".format(__file__).rjust(12)
            return False

        queries = [
            "ALTER TABLE contexts DROP COLUMN edit_type",
            "ALTER TABLE contexts DROP COLUMN admin_type",
            "ALTER TABLE contexts DROP COLUMN explore_projects_visibility",
            "ALTER TABLE contexts DROP COLUMN summary_name",
        ]

        return self.manager.db_downgrade(queries)

    def applied(self):
        """
        Check if column exists or not
        :returns: True if exists, otherwise False
        """
        with admin_query(cursors.DictCursor) as cursor:
            cursor.execute("DESC contexts")
        return "edit_type" in [row["Field"] for row in cursor]


MigrateMgr.instance().add(ContextTableConfiguration())
Example #49
0
        '''
        ]

        return self.manager.db_upgrade(queries)

    def downgrade(self):
        if not self.applied():
            print "project_download table is not in database"
            return True

        queries = [
            'DROP TABLE `project_download`',
        ]
        return self.manager.db_downgrade(queries)

    def applied(self):
        with admin_query() as cursor:
            cursor.execute(
                '''
                SELECT table_name FROM information_schema.tables
                WHERE table_schema = %s
                AND table_name = 'project_download'
            ''', conf.db_admin_schema_name)
            if cursor.rowcount != 1:
                return False

        return True


MigrateMgr.instance().add(CreateProjectDownloadTable())
        # Create image from data
        with open(path, 'w+b') as fd:
            try:
                img = Image.open(StringIO(data))

                # Load the image right away so that we can access the image bands
                img.load()
                bands = img.split()

                # Prevent IOError: cannot write mode RGBA as BMP
                if len(bands) == 3:
                    r, g, b = bands
                    img = Image.merge("RGB", (r, g, b))
                    img.save(path)
                else:
                    # Resize first by keeping the ratio, then convert to have alpha channel and then for to given size
                    img.thumbnail((icon_width, icon_height), Image.ANTIALIAS)
                    img = img.convert("RGBA")
                    img = img.transform((icon_width, icon_height),
                                        Image.EXTENT,
                                        (0, 0, icon_width, icon_height))
                    img.save(path)

            except Exception, err:
                raise IOError('Failed to create image %s, skipping it (%s)' %
                              (path, err))


MigrateMgr.instance().add(ProjectIcons2FS())
            SELECT group_template_id INTO template_key FROM group_template
            WHERE group_template_name = template_name;

            INSERT INTO group_template_permission VALUES(template_key, permission_key);

            COMMIT;

            END
        '''
        ]

        return self.manager.db_downgrade(queries)

    def applied(self):
        """
        Checks from database if the the procedure exists
        """
        conf = Configuration.instance()
        with admin_query() as cursor:
            cursor.execute('''
                SHOW PROCEDURE STATUS
                WHERE
                    Name = 'create_group_from_template' AND
                    Db = '{0}'
            '''.format(conf.db_admin_schema_name))
            return cursor.rowcount == 0


MigrateMgr.instance().add(NukeGroupTemplates())
        UPDATE contexts SET summary_name = 'Development status' WHERE context_name = 'Development status'
        """)

        return self.manager.db_upgrade(queries)

    def downgrade(self):
        if not self.applied():
            print "Migration {0} not applied yet".format(__file__).rjust(12)
            return False

        queries = [
            "ALTER TABLE contexts DROP COLUMN edit_type",
            "ALTER TABLE contexts DROP COLUMN admin_type",
            "ALTER TABLE contexts DROP COLUMN explore_projects_visibility",
            "ALTER TABLE contexts DROP COLUMN summary_name"
        ]

        return self.manager.db_downgrade(queries)

    def applied(self):
        """
        Check if column exists or not
        :returns: True if exists, otherwise False
        """
        with admin_query(cursors.DictCursor) as cursor:
            cursor.execute('DESC contexts')
        return 'edit_type' in [row['Field'] for row in cursor]


MigrateMgr.instance().add(ContextTableConfiguration())
        ALTER TABLE user
        ADD COLUMN created DATETIME DEFAULT NULL
        """]

        return self.manager.db_upgrade(queries)

    def downgrade(self):
        if not self.applied():
            print "Migration {0} not applied yet".format(__file__).rjust(12)
            return False

        queries = ["""
        ALTER TABLE user
        DROP COLUMN created
        """]

        return self.manager.db_downgrade(queries)

    def applied(self):
        """
        Check if column exists or not
        :returns: True if exists, otherwise False
        """
        with admin_query(cursors.DictCursor) as cursor:
            cursor.execute('DESC user')
        return 'created' in [row['Field'] for row in cursor]

MigrateMgr.instance().add(UserCreationField())


    def downgrade(self):
        if not self.applied():
            print "Migration {0} not applied yet".format(__file__).rjust(12)
            return False

        queries = [
            """
            ALTER TABLE trac_admin.user DROP deputies
        """
        ]

        return self.manager.db_downgrade(queries)

    def applied(self):

        with admin_query() as cursor:
            cursor.execute('''
                SELECT COLUMN_NAME FROM information_schema.COLUMNS 
                    WHERE TABLE_SCHEMA = 'trac_admin' 
                    AND TABLE_NAME = 'user' 
                    AND COLUMN_NAME = 'deputies'
            ''')
            row_num = int(cursor.rowcount)
            if row_num == 1:
                return True

        return False


MigrateMgr.instance().add(AddDeputiesForUsers())
                `tag_key` MEDIUMINT(8) UNSIGNED NOT NULL,
                PRIMARY KEY (`project_key`, `tag_key`),
                INDEX `new_fk_constraint2` (`tag_key`),
                CONSTRAINT `new_fk_constraint` FOREIGN KEY (`project_key`) REFERENCES `projects` (`project_id`) ON UPDATE CASCADE ON DELETE CASCADE,
                CONSTRAINT `new_fk_constraint2` FOREIGN KEY (`tag_key`) REFERENCES `tags` (`tag_id`) ON UPDATE CASCADE ON DELETE CASCADE
            )
            COLLATE='utf8_bin'
            ENGINE=InnoDB
            ROW_FORMAT=DEFAULT
            ''']

        return self.manager.db_downgrade(queries)

    def applied(self):
        """
        Check if column exists or not
        :returns: True if exists, otherwise False
        """
        conf = Configuration.instance()
        with admin_query() as cursor:
            cursor.execute('''
                SELECT table_name FROM information_schema.tables
                WHERE table_schema = '{0}'
                AND table_name = 'tags'
            '''.format(conf.db_admin_schema_name))
            return cursor.rowcount != 1

MigrateMgr.instance().add(DropProjectTags())