# Copyright 2012 OpenStack Foundation
#
# 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.

import sqlalchemy as sql


def upgrade(migrate_engine):
    # Upgrade operations go here. Don't create your own engine; bind
    # migrate_engine to your metadata
    meta = sql.MetaData()
    meta.bind = migrate_engine

    # catalog

    service_table = sql.Table(
        'service',
        meta,
        sql.Column('id', sql.String(64), primary_key=True),
        sql.Column('type', sql.String(255)),
        sql.Column('extra', sql.Text()))
    service_table.create(migrate_engine, checkfirst=True)

    endpoint_table = sql.Table(
        'endpoint',
        meta,
        sql.Column('id', sql.String(64), primary_key=True),
        sql.Column('region', sql.String(255)),
        sql.Column('service_id',
                   sql.String(64),
                   sql.ForeignKey('service.id'),
                   nullable=False),
        sql.Column('extra', sql.Text()))
    endpoint_table.create(migrate_engine, checkfirst=True)

    # identity

    role_table = sql.Table(
        'role',
        meta,
        sql.Column('id', sql.String(64), primary_key=True),
        sql.Column('name', sql.String(255), unique=True, nullable=False))
    role_table.create(migrate_engine, checkfirst=True)

    if migrate_engine.name == 'ibm_db_sa':
        # NOTE(blk-u): SQLAlchemy for PostgreSQL picks the name tenant_name_key
        # for the unique constraint, but for DB2 doesn't give the UC a name
        # unless we tell it to and there is no DDL to alter a column to drop
        # an unnamed unique constraint, so this code creates a named unique
        # constraint on the name column rather than an unnamed one.
        # (This is used in migration 16.)
        tenant_table = sql.Table(
            'tenant',
            meta,
            sql.Column('id', sql.String(64), primary_key=True),
            sql.Column('name', sql.String(64), nullable=False),
            sql.Column('extra', sql.Text()),
            sql.UniqueConstraint('name', name='tenant_name_key'))
    else:
        tenant_table = sql.Table(
            'tenant',
            meta,
            sql.Column('id', sql.String(64), primary_key=True),
            sql.Column('name', sql.String(64), unique=True, nullable=False),
            sql.Column('extra', sql.Text()))

    tenant_table.create(migrate_engine, checkfirst=True)

    metadata_table = sql.Table(
        'metadata',
        meta,
        sql.Column('user_id', sql.String(64), primary_key=True),
        sql.Column('tenant_id', sql.String(64), primary_key=True),
        sql.Column('data', sql.Text()))
    metadata_table.create(migrate_engine, checkfirst=True)

    ec2_credential_table = sql.Table(
        'ec2_credential',
        meta,
        sql.Column('access', sql.String(64), primary_key=True),
        sql.Column('secret', sql.String(64)),
        sql.Column('user_id', sql.String(64)),
        sql.Column('tenant_id', sql.String(64)))
    ec2_credential_table.create(migrate_engine, checkfirst=True)

    if migrate_engine.name == 'ibm_db_sa':
        # NOTE(blk-u): SQLAlchemy for PostgreSQL picks the name user_name_key
        # for the unique constraint, but for DB2 doesn't give the UC a name
        # unless we tell it to and there is no DDL to alter a column to drop
        # an unnamed unique constraint, so this code creates a named unique
        # constraint on the name column rather than an unnamed one.
        # (This is used in migration 16.)
        user_table = sql.Table(
            'user',
            meta,
            sql.Column('id', sql.String(64), primary_key=True),
            sql.Column('name', sql.String(64), nullable=False),
            sql.Column('extra', sql.Text()),
            sql.UniqueConstraint('name', name='user_name_key'))
    else:
        user_table = sql.Table(
            'user',
            meta,
            sql.Column('id', sql.String(64), primary_key=True),
            sql.Column('name', sql.String(64), unique=True, nullable=False),
            sql.Column('extra', sql.Text()))

    user_table.create(migrate_engine, checkfirst=True)

    user_tenant_membership_table = sql.Table(
        'user_tenant_membership',
        meta,
        sql.Column(
            'user_id',
            sql.String(64),
            sql.ForeignKey('user.id'),
            primary_key=True),
        sql.Column(
            'tenant_id',
            sql.String(64),
            sql.ForeignKey('tenant.id'),
            primary_key=True))
    user_tenant_membership_table.create(migrate_engine, checkfirst=True)

    # token

    token_table = sql.Table(
        'token',
        meta,
        sql.Column('id', sql.String(64), primary_key=True),
        sql.Column('expires', sql.DateTime()),
        sql.Column('extra', sql.Text()))
    token_table.create(migrate_engine, checkfirst=True)


def downgrade(migrate_engine):
    # Operations to reverse the above upgrade go here.
    meta = sql.MetaData()
    meta.bind = migrate_engine

    tables = ['user_tenant_membership', 'token', 'user', 'tenant', 'role',
              'metadata', 'ec2_credential', 'endpoint', 'service']
    for t in tables:
        table = sql.Table(t, meta, autoload=True)
        table.drop(migrate_engine, checkfirst=True)

[((760, 774), 'sqlalchemy.MetaData', 'sql.MetaData', ([], {}), '()\n', (772, 774), True, 'import sqlalchemy as sql\n'), ((5454, 5468), 'sqlalchemy.MetaData', 'sql.MetaData', ([], {}), '()\n', (5466, 5468), True, 'import sqlalchemy as sql\n'), ((5680, 5713), 'sqlalchemy.Table', 'sql.Table', (['t', 'meta'], {'autoload': '(True)'}), '(t, meta, autoload=True)\n', (5689, 5713), True, 'import sqlalchemy as sql\n'), ((911, 925), 'sqlalchemy.String', 'sql.String', (['(64)'], {}), '(64)\n', (921, 925), True, 'import sqlalchemy as sql\n'), ((973, 988), 'sqlalchemy.String', 'sql.String', (['(255)'], {}), '(255)\n', (983, 988), True, 'import sqlalchemy as sql\n'), ((1019, 1029), 'sqlalchemy.Text', 'sql.Text', ([], {}), '()\n', (1027, 1029), True, 'import sqlalchemy as sql\n'), ((1182, 1196), 'sqlalchemy.String', 'sql.String', (['(64)'], {}), '(64)\n', (1192, 1196), True, 'import sqlalchemy as sql\n'), ((1246, 1261), 'sqlalchemy.String', 'sql.String', (['(255)'], {}), '(255)\n', (1256, 1261), True, 'import sqlalchemy as sql\n'), ((1316, 1330), 'sqlalchemy.String', 'sql.String', (['(64)'], {}), '(64)\n', (1326, 1330), True, 'import sqlalchemy as sql\n'), ((1351, 1379), 'sqlalchemy.ForeignKey', 'sql.ForeignKey', (['"""service.id"""'], {}), "('service.id')\n", (1365, 1379), True, 'import sqlalchemy as sql\n'), ((1445, 1455), 'sqlalchemy.Text', 'sql.Text', ([], {}), '()\n', (1453, 1455), True, 'import sqlalchemy as sql\n'), ((1617, 1631), 'sqlalchemy.String', 'sql.String', (['(64)'], {}), '(64)\n', (1627, 1631), True, 'import sqlalchemy as sql\n'), ((1679, 1694), 'sqlalchemy.String', 'sql.String', (['(255)'], {}), '(255)\n', (1689, 1694), True, 'import sqlalchemy as sql\n'), ((2503, 2555), 'sqlalchemy.UniqueConstraint', 'sql.UniqueConstraint', (['"""name"""'], {'name': '"""tenant_name_key"""'}), "('name', name='tenant_name_key')\n", (2523, 2555), True, 'import sqlalchemy as sql\n'), ((2982, 2996), 'sqlalchemy.String', 'sql.String', (['(64)'], {}), '(64)\n', (2992, 2996), True, 'import sqlalchemy as sql\n'), ((3049, 3063), 'sqlalchemy.String', 'sql.String', (['(64)'], {}), '(64)\n', (3059, 3063), True, 'import sqlalchemy as sql\n'), ((3111, 3121), 'sqlalchemy.Text', 'sql.Text', ([], {}), '()\n', (3119, 3121), True, 'import sqlalchemy as sql\n'), ((3291, 3305), 'sqlalchemy.String', 'sql.String', (['(64)'], {}), '(64)\n', (3301, 3305), True, 'import sqlalchemy as sql\n'), ((3355, 3369), 'sqlalchemy.String', 'sql.String', (['(64)'], {}), '(64)\n', (3365, 3369), True, 'import sqlalchemy as sql\n'), ((3402, 3416), 'sqlalchemy.String', 'sql.String', (['(64)'], {}), '(64)\n', (3412, 3416), True, 'import sqlalchemy as sql\n'), ((3451, 3465), 'sqlalchemy.String', 'sql.String', (['(64)'], {}), '(64)\n', (3461, 3465), True, 'import sqlalchemy as sql\n'), ((4249, 4299), 'sqlalchemy.UniqueConstraint', 'sql.UniqueConstraint', (['"""name"""'], {'name': '"""user_name_key"""'}), "('name', name='user_name_key')\n", (4269, 4299), True, 'import sqlalchemy as sql\n'), ((4773, 4787), 'sqlalchemy.String', 'sql.String', (['(64)'], {}), '(64)\n', (4783, 4787), True, 'import sqlalchemy as sql\n'), ((4801, 4826), 'sqlalchemy.ForeignKey', 'sql.ForeignKey', (['"""user.id"""'], {}), "('user.id')\n", (4815, 4826), True, 'import sqlalchemy as sql\n'), ((4916, 4930), 'sqlalchemy.String', 'sql.String', (['(64)'], {}), '(64)\n', (4926, 4930), True, 'import sqlalchemy as sql\n'), ((4944, 4971), 'sqlalchemy.ForeignKey', 'sql.ForeignKey', (['"""tenant.id"""'], {}), "('tenant.id')\n", (4958, 4971), True, 'import sqlalchemy as sql\n'), ((5176, 5190), 'sqlalchemy.String', 'sql.String', (['(64)'], {}), '(64)\n', (5186, 5190), True, 'import sqlalchemy as sql\n'), ((5241, 5255), 'sqlalchemy.DateTime', 'sql.DateTime', ([], {}), '()\n', (5253, 5255), True, 'import sqlalchemy as sql\n'), ((5286, 5296), 'sqlalchemy.Text', 'sql.Text', ([], {}), '()\n', (5294, 5296), True, 'import sqlalchemy as sql\n'), ((2347, 2361), 'sqlalchemy.String', 'sql.String', (['(64)'], {}), '(64)\n', (2357, 2361), True, 'import sqlalchemy as sql\n'), ((2413, 2427), 'sqlalchemy.String', 'sql.String', (['(64)'], {}), '(64)\n', (2423, 2427), True, 'import sqlalchemy as sql\n'), ((2478, 2488), 'sqlalchemy.Text', 'sql.Text', ([], {}), '()\n', (2486, 2488), True, 'import sqlalchemy as sql\n'), ((2670, 2684), 'sqlalchemy.String', 'sql.String', (['(64)'], {}), '(64)\n', (2680, 2684), True, 'import sqlalchemy as sql\n'), ((2736, 2750), 'sqlalchemy.String', 'sql.String', (['(64)'], {}), '(64)\n', (2746, 2750), True, 'import sqlalchemy as sql\n'), ((2814, 2824), 'sqlalchemy.Text', 'sql.Text', ([], {}), '()\n', (2822, 2824), True, 'import sqlalchemy as sql\n'), ((4093, 4107), 'sqlalchemy.String', 'sql.String', (['(64)'], {}), '(64)\n', (4103, 4107), True, 'import sqlalchemy as sql\n'), ((4159, 4173), 'sqlalchemy.String', 'sql.String', (['(64)'], {}), '(64)\n', (4169, 4173), True, 'import sqlalchemy as sql\n'), ((4224, 4234), 'sqlalchemy.Text', 'sql.Text', ([], {}), '()\n', (4232, 4234), True, 'import sqlalchemy as sql\n'), ((4410, 4424), 'sqlalchemy.String', 'sql.String', (['(64)'], {}), '(64)\n', (4420, 4424), True, 'import sqlalchemy as sql\n'), ((4476, 4490), 'sqlalchemy.String', 'sql.String', (['(64)'], {}), '(64)\n', (4486, 4490), True, 'import sqlalchemy as sql\n'), ((4554, 4564), 'sqlalchemy.Text', 'sql.Text', ([], {}), '()\n', (4562, 4564), True, 'import sqlalchemy as sql\n')]