Consolidate old database migrations

This commit consolidates the migrations between 001 and 048 (inclusive)
into a single database migration, to speed up the process of creating a
new database.

Change-Id: I2718165fc246ad499e6c3b164f557e9ab1580c03
changes/70/510370/3
Adam Coldrick 5 years ago
parent acce431b30
commit d0b595db25

@ -20,6 +20,10 @@ can run sequentially to update the database. The scripts are executed by
storyboard's migration wrapper which uses the Alembic library to manage the
migration.
If your existing database version is currently < 049, you are advised to
run the upgrade command using commit `acce431b30a32497064ad6d1ab3872358e1e60dc`
of this repository, since after that the migrations were consolidated and
will no longer work with existing databases older than version 049.
You can upgrade to the latest database version via:
$ storyboard-db-manage --config-file /path/to/storyboard.conf upgrade head

@ -25,28 +25,37 @@ down_revision = None
from alembic import op
from oslo_log import log
import sqlalchemy as sa
from sqlalchemy.sql.expression import table
from storyboard.db.models import MYSQL_MEDIUM_TEXT
LOG = log.getLogger(__name__)
MYSQL_ENGINE = 'InnoDB'
MYSQL_CHARSET = 'utf8'
def _define_enums():
branch_status = sa.Enum(
'master', 'release', 'stable', 'unsupported',
name='branch_status')
pref_type = sa.Enum('string', 'int', 'bool', 'float')
storyboard_priority = sa.Enum(
'Undefined', 'Low', 'Medium', 'High', 'Critical',
name='priority')
task_priority = sa.Enum(
'low', 'medium', 'high',
name='task_priority')
task_status = sa.Enum(
'Todo', 'In review', 'Landed',
'todo', 'inprogress', 'invalid', 'review', 'merged',
name='task_status')
target_type = sa.Enum(
'task', 'story', 'project', 'project_group',
name='target_type')
return {
'branch_status': branch_status,
'storyboard_priority': storyboard_priority,
'pref_type': pref_type,
'target_type': target_type,
'task_priority': task_priority,
'task_status': task_status
}
@ -55,47 +64,44 @@ def upgrade(active_plugins=None, options=None):
enums = _define_enums()
op.create_table(
'branches',
'project_groups',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('created_at', sa.DateTime(), nullable=True),
sa.Column('updated_at', sa.DateTime(), nullable=True),
sa.Column('name', sa.String(length=50), nullable=True),
sa.Column('status', enums['branch_status'], nullable=True),
sa.Column('release_date', sa.DateTime(), nullable=True),
sa.Column('title', sa.Unicode(length=255), nullable=True),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('name', name='uniq_branch_name'),
sa.UniqueConstraint('name', name='uniq_group_name'),
mysql_engine=MYSQL_ENGINE,
mysql_charset=MYSQL_CHARSET
)
op.create_table(
'project_groups',
'user_preferences',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('created_at', sa.DateTime(), nullable=True),
sa.Column('updated_at', sa.DateTime(), nullable=True),
sa.Column('name', sa.String(length=50), nullable=True),
sa.Column('title', sa.Unicode(length=100), nullable=True),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('name', name='uniq_group_name'),
mysql_engine=MYSQL_ENGINE,
mysql_charset=MYSQL_CHARSET
sa.Column('user_id', sa.Integer(), nullable=False),
sa.Column('key', sa.Unicode(100), nullable=False),
sa.Column('type', enums['pref_type'], nullable=False),
sa.Column('value', sa.Unicode(255), nullable=False),
sa.PrimaryKeyConstraint('id')
)
op.create_table(
'users',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('created_at', sa.DateTime(), nullable=True),
sa.Column('updated_at', sa.DateTime(), nullable=True),
sa.Column('username', sa.Unicode(length=30), nullable=True),
sa.Column('first_name', sa.Unicode(length=30), nullable=True),
sa.Column('last_name', sa.Unicode(length=30), nullable=True),
sa.Column('full_name', sa.Unicode(255), nullable=True),
sa.Column('email', sa.String(length=255), nullable=True),
sa.Column('password', sa.UnicodeText(), nullable=True),
sa.Column('openid', sa.String(255)),
sa.Column('is_staff', sa.Boolean(), nullable=True),
sa.Column('is_active', sa.Boolean(), nullable=True),
sa.Column('is_superuser', sa.Boolean(), nullable=True),
sa.Column('last_login', sa.DateTime(), nullable=True),
sa.Column('enable_login', sa.Boolean(), default=True,
server_default="1", nullable=False),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('email', name='uniq_user_email'),
sa.UniqueConstraint('username', name='uniq_user_username'),
mysql_engine=MYSQL_ENGINE,
mysql_charset=MYSQL_CHARSET
)
@ -158,38 +164,27 @@ def upgrade(active_plugins=None, options=None):
sa.Column('created_at', sa.DateTime(), nullable=True),
sa.Column('updated_at', sa.DateTime(), nullable=True),
sa.Column('creator_id', sa.Integer(), nullable=True),
sa.Column('title', sa.Unicode(length=100), nullable=True),
sa.Column('title', sa.Unicode(length=255), nullable=True),
sa.Column('description', sa.UnicodeText(), nullable=True),
sa.Column('is_bug', sa.Boolean(), nullable=True),
sa.Column('priority', enums['storyboard_priority'], nullable=True),
sa.Column('story_type_id', sa.Integer(), default=1),
sa.ForeignKeyConstraint(['creator_id'], ['users.id'], ),
sa.PrimaryKeyConstraint('id'),
mysql_engine=MYSQL_ENGINE,
mysql_charset=MYSQL_CHARSET
)
op.create_table(
'milestones',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('created_at', sa.DateTime(), nullable=True),
sa.Column('updated_at', sa.DateTime(), nullable=True),
sa.Column('name', sa.String(length=50), nullable=True),
sa.Column('branch_id', sa.Integer(), nullable=True),
sa.Column('released', sa.Boolean(), nullable=True),
sa.Column('undefined', sa.Boolean(), nullable=True),
sa.ForeignKeyConstraint(['branch_id'], ['branches.id'], ),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('name', name='uniq_milestone_name'),
mysql_engine=MYSQL_ENGINE,
mysql_charset=MYSQL_CHARSET
)
op.create_table(
'projects',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('created_at', sa.DateTime(), nullable=True),
sa.Column('updated_at', sa.DateTime(), nullable=True),
sa.Column('name', sa.String(length=50), nullable=True),
sa.Column('description', sa.Unicode(length=100), nullable=True),
sa.Column('description', sa.UnicodeText(), nullable=True),
sa.Column('team_id', sa.Integer(), nullable=True),
sa.Column('is_active', sa.Boolean(), default=True,
server_default='1', nullable=False),
sa.Column('repo_url', sa.String(255), default=None, nullable=True),
sa.Column('autocreate_branches', sa.Boolean(), default=False),
sa.ForeignKeyConstraint(['team_id'], ['teams.id'], ),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('name', name='uniq_project_name'),
@ -211,16 +206,17 @@ def upgrade(active_plugins=None, options=None):
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('created_at', sa.DateTime(), nullable=True),
sa.Column('updated_at', sa.DateTime(), nullable=True),
sa.Column('title', sa.Unicode(length=100), nullable=True),
sa.Column('title', sa.Unicode(length=255), nullable=True),
sa.Column('status', enums['task_status'], nullable=True),
sa.Column('story_id', sa.Integer(), nullable=True),
sa.Column('project_id', sa.Integer(), nullable=True),
sa.Column('assignee_id', sa.Integer(), nullable=True),
sa.Column('creator_id', sa.Integer(), nullable=True),
sa.Column('priority', enums['task_priority'], nullable=True),
sa.Column('branch_id', sa.Integer(), nullable=True),
sa.Column('milestone_id', sa.Integer(), nullable=True),
sa.ForeignKeyConstraint(['assignee_id'], ['users.id'],
name='tasks_ibfk_1'),
sa.ForeignKeyConstraint(['milestone_id'], ['milestones.id'],
name='tasks_ibfk_2'),
sa.ForeignKeyConstraint(['project_id'], ['projects.id'],
name='tasks_ibfk_3'),
sa.ForeignKeyConstraint(['story_id'], ['stories.id'],
@ -230,17 +226,27 @@ def upgrade(active_plugins=None, options=None):
mysql_charset=MYSQL_CHARSET
)
op.create_table(
'comments',
sa.Column('id', sa.Integer(), nullable=False),
'events',
sa.Column('created_at', sa.DateTime(), nullable=True),
sa.Column('updated_at', sa.DateTime(), nullable=True),
sa.Column('action', sa.String(length=150), nullable=True),
sa.Column('comment_type', sa.String(length=20), nullable=True),
sa.Column('content', sa.UnicodeText(), nullable=True),
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('story_id', sa.Integer(), nullable=True),
sa.Column('comment_id', sa.Integer(), nullable=True),
sa.Column('author_id', sa.Integer(), nullable=True),
sa.ForeignKeyConstraint(['author_id'], ['users.id'], ),
sa.ForeignKeyConstraint(['story_id'], ['stories.id'], ),
sa.Column('event_type', sa.Unicode(length=100), nullable=False),
sa.Column('event_info', sa.UnicodeText(), nullable=True),
sa.PrimaryKeyConstraint('id'),
mysql_engine=MYSQL_ENGINE,
mysql_charset=MYSQL_CHARSET
)
op.create_table(
'comments',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('created_at', sa.DateTime(), nullable=True),
sa.Column('updated_at', sa.DateTime(), nullable=True),
sa.Column('content', type_=MYSQL_MEDIUM_TEXT, nullable=True),
sa.Column('is_active', sa.Boolean(), default=True,
server_default='1', nullable=False),
sa.PrimaryKeyConstraint('id'),
mysql_engine=MYSQL_ENGINE,
mysql_charset=MYSQL_CHARSET
@ -250,14 +256,232 @@ def upgrade(active_plugins=None, options=None):
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('created_at', sa.DateTime(), nullable=True),
sa.Column('updated_at', sa.DateTime(), nullable=True),
sa.Column('name', sa.String(length=20), nullable=True),
sa.Column('story_id', sa.Integer(), nullable=True),
sa.ForeignKeyConstraint(['story_id'], ['stories.id'], ),
sa.Column('name', sa.String(length=50), nullable=True),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('name', name='uniq_story_tags_name'),
mysql_engine=MYSQL_ENGINE,
mysql_charset=MYSQL_CHARSET
)
op.create_table('story_storytags',
sa.Column('story_id', sa.Integer(), nullable=True),
sa.Column('storytag_id', sa.Integer(), nullable=True),
mysql_engine=MYSQL_ENGINE,
mysql_charset=MYSQL_CHARSET
)
op.create_table(
'subscriptions',
sa.Column('created_at', sa.DateTime(), nullable=True),
sa.Column('updated_at', sa.DateTime(), nullable=True),
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('user_id', sa.Integer(), nullable=True),
sa.Column('target_type', enums['target_type'], nullable=True),
sa.Column('target_id', sa.Integer(), nullable=True),
sa.PrimaryKeyConstraint('id'),
mysql_engine=MYSQL_ENGINE,
mysql_charset=MYSQL_CHARSET
)
op.create_table(
'subscription_events',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('created_at', sa.DateTime(), nullable=True),
sa.Column('updated_at', sa.DateTime(), nullable=True),
sa.Column('subscriber_id', sa.Integer(), nullable=False),
sa.Column('event_type', sa.Unicode(100), nullable=False),
sa.Column('event_info', sa.UnicodeText(), nullable=True),
sa.Column('author_id', sa.Integer()),
sa.PrimaryKeyConstraint('id'),
mysql_engine=MYSQL_ENGINE,
mysql_charset=MYSQL_CHARSET
)
op.create_table(
'authorizationcodes',
sa.Column('created_at', sa.DateTime(), nullable=True),
sa.Column('updated_at', sa.DateTime(), nullable=True),
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('code', sa.Unicode(100), nullable=False),
sa.Column('state', sa.Unicode(100), nullable=False),
sa.Column('user_id', sa.Integer(), nullable=False),
sa.Column('expires_in', sa.Integer(), nullable=False),
sa.ForeignKeyConstraint(['user_id'], ['users.id'], ),
sa.PrimaryKeyConstraint('id'),
mysql_engine=MYSQL_ENGINE,
mysql_charset=MYSQL_CHARSET
)
op.create_table(
'accesstokens',
sa.Column('created_at', sa.DateTime(), nullable=True),
sa.Column('updated_at', sa.DateTime(), nullable=True),
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('user_id', sa.Integer(), nullable=False),
sa.Column('access_token', sa.Unicode(length=100), nullable=False),
sa.Column('expires_in', sa.Integer(), nullable=False),
sa.Column('expires_at', sa.DateTime(), nullable=False),
sa.ForeignKeyConstraint(['user_id'], ['users.id'], ),
sa.PrimaryKeyConstraint('id'),
mysql_default_charset=MYSQL_CHARSET,
mysql_engine=MYSQL_ENGINE
)
op.create_table(
'refreshtokens',
sa.Column('created_at', sa.DateTime(), nullable=True),
sa.Column('updated_at', sa.DateTime(), nullable=True),
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('user_id', sa.Integer(), nullable=False),
sa.Column('refresh_token', sa.Unicode(length=100), nullable=False),
sa.Column('expires_at', sa.DateTime(), nullable=False),
sa.Column('expires_in', sa.Integer(), nullable=False),
sa.Column('access_token_id', sa.Integer(), nullable=False),
sa.ForeignKeyConstraint(['user_id'], ['users.id'], ),
sa.PrimaryKeyConstraint('id'),
mysql_default_charset=MYSQL_CHARSET,
mysql_engine=MYSQL_ENGINE
)
op.create_table(
'branches',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('name', sa.String(100), nullable=True),
sa.Column('project_id', sa.Integer(), nullable=True),
sa.Column('created_at', sa.DateTime(), nullable=True),
sa.Column('updated_at', sa.DateTime(), nullable=True),
sa.Column('expired', sa.Boolean(), default=False, nullable=True),
sa.Column('expiration_date', sa.DateTime(), default=None,
nullable=True),
sa.Column('autocreated', sa.Boolean(), default=False, nullable=True),
sa.Column('restricted', sa.Boolean(), default=False),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('name', 'project_id', name="branch_un_constr"),
mysql_engine=MYSQL_ENGINE,
mysql_charset=MYSQL_CHARSET
)
op.create_table(
'milestones',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('name', sa.String(100), nullable=True),
sa.Column('branch_id', sa.Integer(), nullable=True),
sa.Column('created_at', sa.DateTime(), nullable=True),
sa.Column('updated_at', sa.DateTime(), nullable=True),
sa.Column('expired', sa.Boolean(), default=False, nullable=True),
sa.Column('expiration_date', sa.DateTime(), default=None),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('name', 'branch_id', name="milestone_un_constr"),
mysql_engine=MYSQL_ENGINE,
mysql_charset=MYSQL_CHARSET
)
op.create_table(
'story_types',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('created_at', sa.DateTime(), nullable=True),
sa.Column('updated_at', sa.DateTime(), nullable=True),
sa.Column('name', sa.String(50), nullable=True),
sa.Column('icon', sa.String(50), nullable=True),
sa.Column('restricted', sa.Boolean(), default=False),
sa.Column('private', sa.Boolean(), default=False),
sa.Column('visible', sa.Boolean(), default=True),
sa.PrimaryKeyConstraint('id'),
mysql_engine=MYSQL_ENGINE,
mysql_charset=MYSQL_CHARSET
)
op.create_table(
'may_mutate_to',
sa.Column('story_type_id_from', sa.Integer(), nullable=False),
sa.Column('story_type_id_to', sa.Integer(), nullable=False),
sa.UniqueConstraint('story_type_id_from',
'story_type_id_to',
name="mutate_un_constr"),
sa.PrimaryKeyConstraint(),
mysql_engine=MYSQL_ENGINE,
mysql_charset=MYSQL_CHARSET
)
# Create story types
bind = op.get_bind()
story_types_table = table(
'story_types',
sa.Column('name', sa.String(50), nullable=True),
sa.Column('icon', sa.String(50), nullable=True),
sa.Column('restricted', sa.Boolean(), default=False),
sa.Column('private', sa.Boolean(), default=False),
sa.Column('visible', sa.Boolean(), default=True),
)
bind.execute(story_types_table.insert().values(
name='bug',
icon='fa-bug'
))
bind.execute(story_types_table.insert().values(
name='feature',
icon='fa-lightbulb-o',
restricted=True
))
bind.execute(story_types_table.insert().values(
name='private_vulnerability',
icon='fa-lock',
private=True
))
bind.execute(story_types_table.insert().values(
name='public_vulnerability',
icon='fa-bomb',
visible=False
))
# Populate may_mutate_to
may_mutate_to = table(
'may_mutate_to',
sa.Column('story_type_id_from', sa.Integer(), nullable=False),
sa.Column('story_type_id_to', sa.Integer(), nullable=False),
)
bind.execute(may_mutate_to.insert().values(
story_type_id_from=1,
story_type_id_to=4
))
bind.execute(may_mutate_to.insert().values(
story_type_id_from=1,
story_type_id_to=2
))
bind.execute(may_mutate_to.insert().values(
story_type_id_from=2,
story_type_id_to=1
))
bind.execute(may_mutate_to.insert().values(
story_type_id_from=3,
story_type_id_to=4
))
bind.execute(may_mutate_to.insert().values(
story_type_id_from=3,
story_type_id_to=1
))
bind.execute(may_mutate_to.insert().values(
story_type_id_from=4,
story_type_id_to=1
))
op.create_index('accesstokens_access_token_idx',
'accesstokens', ['access_token'])
version_info = op.get_bind().engine.dialect.server_version_info
if version_info[-1] == "MariaDB":
# Removes fake mysql prefix
version_info = version_info[-4:]
if version_info[0] < 5 or version_info[0] == 5 and version_info[1] < 6:
LOG.warning(
"MySQL version is lower than 5.6. Skipping full-text indexes")
return
# Index for projects
op.execute("ALTER TABLE projects "
"ADD FULLTEXT projects_fti (name, description)")
# Index for stories
op.execute("ALTER TABLE stories "
"ADD FULLTEXT stories_fti (title, description)")
# Index for tasks
op.execute("ALTER TABLE tasks ADD FULLTEXT tasks_fti (title)")
# Index for comments
op.execute("ALTER TABLE comments ADD FULLTEXT comments_fti (content)")
# Index for users
op.execute("ALTER TABLE users ADD FULLTEXT users_fti (full_name, email)")
def downgrade(active_plugins=None, options=None):
@ -267,6 +491,7 @@ def downgrade(active_plugins=None, options=None):
op.drop_table('team_permissions')
op.drop_table('user_permissions')
op.drop_table('storytags')
op.drop_table('story_storytags')
op.drop_table('comments')
op.drop_table('tasks')
op.drop_table('projects')
@ -277,6 +502,16 @@ def downgrade(active_plugins=None, options=None):
op.drop_table('users')
op.drop_table('project_groups')
op.drop_table('branches')
op.drop_table('authorizationcodes')
op.drop_table('refreshtokens')
op.drop_table('accesstokens')
op.drop_table('subscriptions')
op.drop_table('subscription_events')
op.drop_table('user_preferences')
op.drop_table('branches')
op.drop_table('milestones')
op.drop_table('story_types')
op.drop_table('may_mutate_to')
# Need to explicitly delete enums during migrations for Postgres
enums = _define_enums()

@ -1,43 +0,0 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
"""user update
Revision ID: 002
Revises: 001
Create Date: 2014-02-21 13:21:59.917098
"""
# revision identifiers, used by Alembic.
revision = '002'
down_revision = '001'
from alembic import op
import sqlalchemy as sa
MYSQL_ENGINE = 'InnoDB'
MYSQL_CHARSET = 'utf8'
def upgrade(active_plugins=None, options=None):
op.drop_column('users', 'password')
op.add_column('users', sa.Column('openid', sa.String(255)))
def downgrade(active_plugins=None, options=None):
op.add_column('users', sa.Column('password', sa.UnicodeText))
op.drop_column('users', 'openid')

@ -1,43 +0,0 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
"""deletion states
Revision ID: 003
Revises: 002
Create Date: 2014-03-03 16:08:12.584302
"""
# revision identifiers, used by Alembic.
revision = '003'
down_revision = '002'
from alembic import op
from sqlalchemy import Boolean
from sqlalchemy import Column
def upgrade(active_plugins=None, options=None):
op.add_column('projects',
Column('is_active', Boolean(), default=True))
op.add_column('stories',
Column('is_active', Boolean(), default=True))
op.add_column('tasks',
Column('is_active', Boolean(), default=True))
def downgrade(active_plugins=None, options=None):
op.drop_column('projects', 'is_active')
op.drop_column('stories', 'is_active')
op.drop_column('tasks', 'is_active')

@ -1,44 +0,0 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
"""Expand project description
Revision ID: 004
Revises: 003
Create Date: 2014-03-05 17:03:12.978207
"""
# revision identifiers, used by Alembic.
revision = '004'
down_revision = '003'
from alembic import op
import sqlalchemy as sa
MYSQL_ENGINE = 'InnoDB'
MYSQL_CHARSET = 'utf8'
def upgrade(active_plugins=None, options=None):
op.alter_column(
'projects', 'description',
type_=sa.UnicodeText)
def downgrade(active_plugins=None, options=None):
op.alter_column(
'projects', 'description',
type_=sa.Unicode(100))

@ -1,73 +0,0 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
"""empty message
Revision ID: 005
Revises: 004
Create Date: 2014-03-10 14:24:09.622503
"""
# revision identifiers, used by Alembic.
revision = '005'
down_revision = '004'
from alembic import op
from sqlalchemy import Boolean
from sqlalchemy import Column
def upgrade(active_plugins=None, options=None):
op.drop_column('projects', 'is_active')
op.add_column('projects',
Column('is_active',
Boolean(),
default=True,
server_default="1",
nullable=False))
op.drop_column('stories', 'is_active')
op.add_column('stories',
Column('is_active',
Boolean(),
default=True,
server_default="1",
nullable=False))
op.drop_column('tasks', 'is_active')
op.add_column('tasks',
Column('is_active',
Boolean(),
default=True,
server_default="1",
nullable=False))
def downgrade(active_plugins=None, options=None):
op.drop_column('projects', 'is_active')
op.add_column('projects',
Column('is_active',
Boolean(),
default=True,
nullable=False))
op.drop_column('stories', 'is_active')
op.add_column('stories',
Column('is_active',
Boolean(),
default=True,
nullable=False))
op.drop_column('tasks', 'is_active')
op.add_column('tasks',
Column('is_active',
Boolean(),
default=True,
nullable=False))

@ -1,61 +0,0 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
"""Converts the user object to use full_name
Revision ID: 56bda170aa42
Revises: 128470dcd02f
Create Date: 2014-03-11 10:45:59.122062
"""
# revision identifiers, used by Alembic.
revision = '006'
down_revision = '005'
from alembic import op
import sqlalchemy as sa
from sqlalchemy.sql.expression import column
from sqlalchemy.sql.expression import table
def upgrade(active_plugins=None, options=None):
op.add_column(
'users',
sa.Column('full_name', sa.Unicode(255), nullable=True)
)
users = table(
'users',
column('first_name', sa.Unicode(30)),
column('last_name', sa.Unicode(30)),
column('full_name', sa.Unicode(255))
)
users.update().values(
{'full_name': column('first_name') + op.inline_literal(' ') + column(
'last_name')})
op.drop_column('users', 'first_name')
op.drop_column('users', 'last_name')
def downgrade(active_plugins=None, options=None):
op.add_column(
'users',
sa.Column('first_name', sa.Unicode(length=30), nullable=True)
)
op.add_column(
'users',
sa.Column('last_name', sa.Unicode(length=30), nullable=True)
)
op.drop_column('users', 'full_name')

@ -1,41 +0,0 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
"""empty message
Revision ID: 007
Revises: 006
Create Date: 2014-04-18 14:55:09.622503
"""
# revision identifiers, used by Alembic.
revision = '007'
down_revision = '006'
from alembic import op
from sqlalchemy import Boolean
from sqlalchemy import Column
def upgrade(active_plugins=None, options=None):
op.add_column('comments',
Column('is_active',
Boolean(),
default=True,
server_default="1",
nullable=False))
def downgrade(active_plugins=None, options=None):
op.drop_column('comments', 'is_active')

@ -1,92 +0,0 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
"""Remove Branch, Milestone tables
Revision ID: 008
Revises: 007
Create Date: 2014-03-19 15:00:39.149963
"""
# revision identifiers, used by Alembic.
revision = '008'
down_revision = '007'
from alembic import op
import sqlalchemy as sa
MYSQL_ENGINE = 'InnoDB'
MYSQL_CHARSET = 'utf8'
def _define_enums():
branch_status = sa.Enum(
'master', 'release', 'stable', 'unsupported',
name='branch_status')
return {
'branch_status': branch_status
}
def upgrade(active_plugins=None, options=None):
op.drop_constraint('tasks_ibfk_2',
'tasks', type_='foreignkey')
op.drop_column('tasks', 'milestone_id')
op.drop_table('milestones')
op.drop_table('branches')
# Need to explicitly delete enums during migrations for Postgres
enums = _define_enums()
for enum in enums.values():
enum.drop(op.get_bind())
def downgrade(active_plugins=None, options=None):
enums = _define_enums()
op.create_table(
'branches',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('created_at', sa.DateTime(), nullable=True),
sa.Column('updated_at', sa.DateTime(), nullable=True),
sa.Column('name', sa.String(length=50), nullable=True),
sa.Column('status', enums['branch_status'], nullable=True),
sa.Column('release_date', sa.DateTime(), nullable=True),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('name', name='uniq_branch_name'),
mysql_engine=MYSQL_ENGINE,
mysql_charset=MYSQL_CHARSET
)
op.create_table(
'milestones',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('created_at', sa.DateTime(), nullable=True),
sa.Column('updated_at', sa.DateTime(), nullable=True),
sa.Column('name', sa.String(length=50), nullable=True),
sa.Column('branch_id', sa.Integer(), nullable=True),
sa.Column('released', sa.Boolean(), nullable=True),
sa.Column('undefined', sa.Boolean(), nullable=True),
sa.ForeignKeyConstraint(['branch_id'], ['branches.id'], ),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('name', name='uniq_milestone_name'),
mysql_engine=MYSQL_ENGINE,
mysql_charset=MYSQL_CHARSET
)
op.add_column('tasks', sa.Column('milestone_id',
sa.Integer(),
nullable=True))
op.create_foreign_key('tasks_ibfk_2', 'tasks',
'milestones', ['milestone_id'], ['id'])

@ -1,61 +0,0 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
"""Remove legacy priority column
Revision ID: 010
Revises: 008
Create Date: 2014-03-24 14:00:19.159763
"""
# revision identifiers, used by Alembic.
# 009 is skipped on purpose due to a deployment sequencing bug
revision = '010'
down_revision = '008'
from alembic import op
import sqlalchemy as sa
MYSQL_ENGINE = 'InnoDB'
MYSQL_CHARSET = 'utf8'
def _define_enums():
storyboard_priority = sa.Enum(
'Undefined', 'Low', 'Medium', 'High', 'Critical',
name='priority')
return {
'storyboard_priority': storyboard_priority
}
def upgrade(active_plugins=None, options=None):
op.drop_column('stories', 'priority')
# Need to explicitly delete enums during migrations for Postgres
enums = _define_enums()
for enum in enums.values():
enum.drop(op.get_bind())
def downgrade(active_plugins=None, options=None):
enums = _define_enums()
for enum in enums.values():
enum.create(op.get_bind())
op.add_column('stories', sa.Column('priority',
enums['storyboard_priority'],
nullable=True))

@ -1,74 +0,0 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
"""Add authorization models
Revision ID: 011
Revises: 010
Create Date: 2014-03-21 17:44:51.248232
"""
# revision identifiers, used by Alembic.
revision = '011'
down_revision = '010'
from alembic import op
import sqlalchemy as sa
MYSQL_ENGINE = 'InnoDB'
MYSQL_CHARSET = 'utf8'
def upgrade(active_plugins=None, options=None):
op.create_table(
'authorizationcodes',
sa.Column('created_at', sa.DateTime(), nullable=True),
sa.Column('updated_at', sa.DateTime(), nullable=True),
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('code', sa.Unicode(100), nullable=False),
sa.Column('state', sa.Unicode(100), nullable=False),
sa.Column('user_id', sa.Integer(), nullable=False),
sa.Column('is_active', sa.Boolean(), default=True, server_default="1",
nullable=False),
sa.ForeignKeyConstraint(['user_id'], ['users.id'], ),
sa.PrimaryKeyConstraint('id'),
mysql_engine=MYSQL_ENGINE,
mysql_charset=MYSQL_CHARSET
)
op.create_table(
'bearertokens',
sa.Column('created_at', sa.DateTime(), nullable=True),
sa.Column('updated_at', sa.DateTime(), nullable=True),
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('user_id', sa.Integer(), nullable=False),
sa.Column('access_token', sa.Unicode(100), nullable=False),
sa.Column('refresh_token', sa.Unicode(100), nullable=False),
sa.Column('expires_in', sa.Integer(), nullable=False),
sa.Column('expires_at', sa.DateTime(), nullable=False),
sa.Column('is_active', sa.Boolean(), default=True, server_default="1",
nullable=False),
sa.ForeignKeyConstraint(['user_id'], ['users.id'], ),
sa.PrimaryKeyConstraint('id'),
mysql_engine=MYSQL_ENGINE,
mysql_charset=MYSQL_CHARSET
)
def downgrade(active_plugins=None, options=None):
op.drop_table('bearertokens')
op.drop_table('authorizationcodes')

@ -1,63 +0,0 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
"""Update task states
Revision ID: 011
Revises: 010
Create Date: 2014-03-21 17:44:51.248232
"""
# revision identifiers, used by Alembic.
revision = '012'
down_revision = '011'
from alembic import op
import sqlalchemy as sa
MYSQL_ENGINE = 'InnoDB'
MYSQL_CHARSET = 'utf8'
def _define_enums():
task_status_old = sa.Enum(
'Todo', 'In review', 'Landed',
name='task_status')
task_status_new = sa.Enum(
'todo', 'inprogress', 'invalid', 'review', 'merged',
name='task_status')
return {
'task_status_old': task_status_old,
'task_status_new': task_status_new
}
def upgrade(active_plugins=None, options=None):
enums = _define_enums()
op.drop_column('tasks', 'status')
op.add_column('tasks', sa.Column('status',
enums['task_status_new'],
nullable=True))
def downgrade(active_plugins=None, options=None):
enums = _define_enums()
op.drop_column('tasks', 'status')
op.add_column('tasks', sa.Column('status',
enums['task_status_old'],
nullable=True))

@ -1,102 +0,0 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
"""Split Access and Refresh tokens to separate tables.
Remove is_active fields as unnecessary.
Expired access tokens and authorization codes will be hard deleted.
Refresh tokens should live forever.
Revision ID: 013
Revises: 012
Create Date: 2014-04-09 13:01:18.536369
"""
# revision identifiers, used by Alembic.
revision = '013'
down_revision = '012'
from alembic import op
import sqlalchemy as sa
MYSQL_ENGINE = 'InnoDB'
MYSQL_CHARSET = 'utf8'
def upgrade(active_plugins=None, options=None):
### commands auto generated by Alembic - please adjust! ###
op.create_table(
'accesstokens',
sa.Column('created_at', sa.DateTime(), nullable=True),
sa.Column('updated_at', sa.DateTime(), nullable=True),
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('user_id', sa.Integer(), nullable=False),
sa.Column('access_token', sa.Unicode(length=100), nullable=False),
sa.Column('expires_in', sa.Integer(), nullable=False),
sa.Column('expires_at', sa.DateTime(), nullable=False),
sa.ForeignKeyConstraint(['user_id'], ['users.id'], ),
sa.PrimaryKeyConstraint('id'),
mysql_default_charset=MYSQL_CHARSET,
mysql_engine=MYSQL_ENGINE)
op.create_table(
'refreshtokens',
sa.Column('created_at', sa.DateTime(), nullable=True),
sa.Column('updated_at', sa.DateTime(), nullable=True),
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('user_id', sa.Integer(), nullable=False),
sa.Column('refresh_token', sa.Unicode(length=100), nullable=False),
sa.ForeignKeyConstraint(['user_id'], ['users.id'], ),
sa.PrimaryKeyConstraint('id'),
mysql_default_charset=MYSQL_CHARSET,
mysql_engine=MYSQL_ENGINE)
op.drop_table(u'bearertokens')
op.drop_column(u'authorizationcodes', u'is_active')
### end Alembic commands ###
def downgrade(active_plugins=None, options=None):
### commands auto generated by Alembic - please adjust! ###
op.add_column(u'authorizationcodes',
sa.Column('is_active', sa.Boolean(), default=True,
server_default="1",
nullable=False))
op.create_table(
u'bearertokens',
sa.Column(u'created_at', sa.DateTime(), nullable=True),
sa.Column(u'updated_at', sa.DateTime(), nullable=True),
sa.Column(u'id', sa.Integer(), nullable=False),
sa.Column(u'user_id', sa.Integer(), nullable=False),
sa.Column(u'access_token', sa.Unicode(length=100), nullable=False),
sa.Column(u'refresh_token', sa.Unicode(length=100), nullable=False),
sa.Column(u'expires_in', sa.Integer(), nullable=False),
sa.Column(u'expires_at', sa.DateTime(), nullable=False),
sa.Column(u'is_active', sa.Column('is_active', sa.Boolean(),
default=True,
server_default="1",
nullable=False)),
sa.ForeignKeyConstraint(['user_id'], [u'users.id'],
name=u'bearertokens_ibfk_1'),
sa.PrimaryKeyConstraint(u'id'),
mysql_default_charset=MYSQL_CHARSET,
mysql_engine=MYSQL_ENGINE)
op.drop_table('refreshtokens')
op.drop_table('accesstokens')
### end Alembic commands ###

@ -1,48 +0,0 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
"""Remove is_active from tasks.
Revision ID: 014
Revises: 013
Create Date: 2014-04-09 16:52:36.375926
"""
# revision identifiers, used by Alembic.
revision = '014'
down_revision = '013'
from alembic import op
import sqlalchemy as sa
def upgrade(active_plugins=None, options=None):
### commands auto generated by Alembic - please adjust! ###
op.drop_column(u'tasks', u'is_active')
### end Alembic commands ###
def downgrade(active_plugins=None, options=None):
### commands auto generated by Alembic - please adjust! ###
op.add_column(u'tasks',
sa.Column('is_active', sa.Boolean(), default=True,
server_default="1",
nullable=False))
### end Alembic commands ###

@ -1,48 +0,0 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
"""Remove is_active from stories.
Revision ID: 015
Revises: 014
Create Date: 2014-04-09 16:52:36.375926
"""
# revision identifiers, used by Alembic.
revision = '015'
down_revision = '014'
from alembic import op
import sqlalchemy as sa
def upgrade(active_plugins=None, options=None):
### commands auto generated by Alembic - please adjust! ###
op.drop_column(u'stories', u'is_active')
### end Alembic commands ###
def downgrade(active_plugins=None, options=None):
### commands auto generated by Alembic - please adjust! ###
op.add_column(u'stories',
sa.Column('is_active', sa.Boolean(), default=True,
server_default="1",
nullable=False))
### end Alembic commands ###

@ -1,43 +0,0 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
"""We need to know who has created a task.
Revision ID: 016
Revises: 015
Create Date: 2014-04-15 17:16:07.368141
"""
# revision identifiers, used by Alembic.
revision = '016'
down_revision = '015'
from alembic import op
import sqlalchemy as sa
def upgrade(active_plugins=None, options=None):
### commands auto generated by Alembic - please adjust! ###