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
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 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())
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())
""" 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())
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())
''' ] 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())
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())
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())
""" ] 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())
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())
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())
''' ] 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())
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())