# 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)

[((21, 11, 21, 25), 'sqlalchemy.MetaData', 'sql.MetaData', ({}, {}), '()', True, 'import sqlalchemy as sql\n'), ((148, 11, 148, 25), 'sqlalchemy.MetaData', 'sql.MetaData', ({}, {}), '()', True, 'import sqlalchemy as sql\n'), ((154, 16, 154, 49), 'sqlalchemy.Table', 'sql.Table', (), '', True, 'import sqlalchemy as sql\n'), ((29, 25, 29, 39), 'sqlalchemy.String', 'sql.String', ({(29, 36, 29, 38): '64'}, {}), '(64)', True, 'import sqlalchemy as sql\n'), ((30, 27, 30, 42), 'sqlalchemy.String', 'sql.String', ({(30, 38, 30, 41): '255'}, {}), '(255)', True, 'import sqlalchemy as sql\n'), ((31, 28, 31, 38), 'sqlalchemy.Text', 'sql.Text', ({}, {}), '()', True, 'import sqlalchemy as sql\n'), ((37, 25, 37, 39), 'sqlalchemy.String', 'sql.String', ({(37, 36, 37, 38): '64'}, {}), '(64)', True, 'import sqlalchemy as sql\n'), ((38, 29, 38, 44), 'sqlalchemy.String', 'sql.String', ({(38, 40, 38, 43): '255'}, {}), '(255)', True, 'import sqlalchemy as sql\n'), ((40, 19, 40, 33), 'sqlalchemy.String', 'sql.String', ({(40, 30, 40, 32): '64'}, {}), '(64)', True, 'import sqlalchemy as sql\n'), ((41, 19, 41, 47), 'sqlalchemy.ForeignKey', 'sql.ForeignKey', ({(41, 34, 41, 46): '"""service.id"""'}, {}), "('service.id')", True, 'import sqlalchemy as sql\n'), ((43, 28, 43, 38), 'sqlalchemy.Text', 'sql.Text', ({}, {}), '()', True, 'import sqlalchemy as sql\n'), ((51, 25, 51, 39), 'sqlalchemy.String', 'sql.String', ({(51, 36, 51, 38): '64'}, {}), '(64)', True, 'import sqlalchemy as sql\n'), ((52, 27, 52, 42), 'sqlalchemy.String', 'sql.String', ({(52, 38, 52, 41): '255'}, {}), '(255)', True, 'import sqlalchemy as sql\n'), ((68, 12, 68, 64), 'sqlalchemy.UniqueConstraint', 'sql.UniqueConstraint', (), '', True, 'import sqlalchemy as sql\n'), ((82, 30, 82, 44), 'sqlalchemy.String', 'sql.String', ({(82, 41, 82, 43): '64'}, {}), '(64)', True, 'import sqlalchemy as sql\n'), ((83, 32, 83, 46), 'sqlalchemy.String', 'sql.String', ({(83, 43, 83, 45): '64'}, {}), '(64)', True, 'import sqlalchemy as sql\n'), ((84, 27, 84, 37), 'sqlalchemy.Text', 'sql.Text', ({}, {}), '()', True, 'import sqlalchemy as sql\n'), ((90, 29, 90, 43), 'sqlalchemy.String', 'sql.String', ({(90, 40, 90, 42): '64'}, {}), '(64)', True, 'import sqlalchemy as sql\n'), ((91, 29, 91, 43), 'sqlalchemy.String', 'sql.String', ({(91, 40, 91, 42): '64'}, {}), '(64)', True, 'import sqlalchemy as sql\n'), ((92, 30, 92, 44), 'sqlalchemy.String', 'sql.String', ({(92, 41, 92, 43): '64'}, {}), '(64)', True, 'import sqlalchemy as sql\n'), ((93, 32, 93, 46), 'sqlalchemy.String', 'sql.String', ({(93, 43, 93, 45): '64'}, {}), '(64)', True, 'import sqlalchemy as sql\n'), ((109, 12, 109, 62), 'sqlalchemy.UniqueConstraint', 'sql.UniqueConstraint', (), '', True, 'import sqlalchemy as sql\n'), ((125, 12, 125, 26), 'sqlalchemy.String', 'sql.String', ({(125, 23, 125, 25): '64'}, {}), '(64)', True, 'import sqlalchemy as sql\n'), ((126, 12, 126, 37), 'sqlalchemy.ForeignKey', 'sql.ForeignKey', ({(126, 27, 126, 36): '"""user.id"""'}, {}), "('user.id')", True, 'import sqlalchemy as sql\n'), ((130, 12, 130, 26), 'sqlalchemy.String', 'sql.String', ({(130, 23, 130, 25): '64'}, {}), '(64)', True, 'import sqlalchemy as sql\n'), ((131, 12, 131, 39), 'sqlalchemy.ForeignKey', 'sql.ForeignKey', ({(131, 27, 131, 38): '"""tenant.id"""'}, {}), "('tenant.id')", True, 'import sqlalchemy as sql\n'), ((140, 25, 140, 39), 'sqlalchemy.String', 'sql.String', ({(140, 36, 140, 38): '64'}, {}), '(64)', True, 'import sqlalchemy as sql\n'), ((141, 30, 141, 44), 'sqlalchemy.DateTime', 'sql.DateTime', ({}, {}), '()', True, 'import sqlalchemy as sql\n'), ((142, 28, 142, 38), 'sqlalchemy.Text', 'sql.Text', ({}, {}), '()', True, 'import sqlalchemy as sql\n'), ((65, 29, 65, 43), 'sqlalchemy.String', 'sql.String', ({(65, 40, 65, 42): '64'}, {}), '(64)', True, 'import sqlalchemy as sql\n'), ((66, 31, 66, 45), 'sqlalchemy.String', 'sql.String', ({(66, 42, 66, 44): '64'}, {}), '(64)', True, 'import sqlalchemy as sql\n'), ((67, 32, 67, 42), 'sqlalchemy.Text', 'sql.Text', ({}, {}), '()', True, 'import sqlalchemy as sql\n'), ((73, 29, 73, 43), 'sqlalchemy.String', 'sql.String', ({(73, 40, 73, 42): '64'}, {}), '(64)', True, 'import sqlalchemy as sql\n'), ((74, 31, 74, 45), 'sqlalchemy.String', 'sql.String', ({(74, 42, 74, 44): '64'}, {}), '(64)', True, 'import sqlalchemy as sql\n'), ((75, 32, 75, 42), 'sqlalchemy.Text', 'sql.Text', ({}, {}), '()', True, 'import sqlalchemy as sql\n'), ((106, 29, 106, 43), 'sqlalchemy.String', 'sql.String', ({(106, 40, 106, 42): '64'}, {}), '(64)', True, 'import sqlalchemy as sql\n'), ((107, 31, 107, 45), 'sqlalchemy.String', 'sql.String', ({(107, 42, 107, 44): '64'}, {}), '(64)', True, 'import sqlalchemy as sql\n'), ((108, 32, 108, 42), 'sqlalchemy.Text', 'sql.Text', ({}, {}), '()', True, 'import sqlalchemy as sql\n'), ((114, 29, 114, 43), 'sqlalchemy.String', 'sql.String', ({(114, 40, 114, 42): '64'}, {}), '(64)', True, 'import sqlalchemy as sql\n'), ((115, 31, 115, 45), 'sqlalchemy.String', 'sql.String', ({(115, 42, 115, 44): '64'}, {}), '(64)', True, 'import sqlalchemy as sql\n'), ((116, 32, 116, 42), 'sqlalchemy.Text', 'sql.Text', ({}, {}), '()', True, 'import sqlalchemy as sql\n')]