# -*- encoding: utf-8 -*-
#
#
# 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.

from migrate import ForeignKeyConstraint
from sqlalchemy import MetaData, Table

TABLES = ['resource', 'sourceassoc', 'user',
          'project', 'meter', 'source', 'alarm']

INDEXES = {
    "resource": (('user_id', 'user', 'id'),
                 ('project_id', 'project', 'id')),
    "sourceassoc": (('user_id', 'user', 'id'),
                    ('project_id', 'project', 'id'),
                    ('resource_id', 'resource', 'id'),
                    ('meter_id', 'meter', 'id'),
                    ('source_id', 'source', 'id')),
    "alarm": (('user_id', 'user', 'id'),
              ('project_id', 'project', 'id')),
    "meter": (('user_id', 'user', 'id'),
              ('project_id', 'project', 'id'),
              ('resource_id', 'resource', 'id'),)
}


def upgrade(migrate_engine):
    meta = MetaData(bind=migrate_engine)
    load_tables = dict((table_name, Table(table_name, meta, autoload=True))
                       for table_name in TABLES)
    for table_name, indexes in INDEXES.items():
        table = load_tables[table_name]
        for column, ref_table_name, ref_column_name in indexes:
            ref_table = load_tables[ref_table_name]
            params = {'columns': [table.c[column]],
                      'refcolumns': [ref_table.c[ref_column_name]]}
            if migrate_engine.name == 'mysql':
                params['name'] = "_".join(('fk', table_name, column))
            fkey = ForeignKeyConstraint(**params)
            fkey.create()


def downgrade(migrate_engine):
    meta = MetaData(bind=migrate_engine)
    load_tables = dict((table_name, Table(table_name, meta, autoload=True))
                       for table_name in TABLES)
    for table_name, indexes in INDEXES.items():
        table = load_tables[table_name]
        for column, ref_table_name, ref_column_name in indexes:
            ref_table = load_tables[ref_table_name]
            params = {'columns': [table.c[column]],
                      'refcolumns': [ref_table.c[ref_column_name]]}
            if migrate_engine.name == 'mysql':
                params['name'] = "_".join(('fk', table_name, column))
            fkey = ForeignKeyConstraint(**params)
            fkey.drop()

@@ -648,16 +648,122 @@
 a, Table
+%0Afrom sqlalchemy.sql.expression import select%0A%0Afrom ceilometer.openstack.common.db.sqlalchemy import utils
 %0A%0ATABLES
@@ -1466,32 +1466,87 @@
 igrate_engine):%0A
+    if migrate_engine.name == 'sqlite':%0A        return%0A
     meta = MetaD
@@ -1787,123 +1787,704 @@
 me%5D%0A
-        for column, ref_table_name, ref_column_name in indexes:%0A            ref_table = load_tables%5Bref_table_name%5D
+%0A        # Save data that conflicted with FK.%0A        columns = %5Bcolumn.copy() for column in table.columns%5D%0A        table_dump = Table('dump_' + table_name, meta, *columns)%0A        table_dump.create()%0A        for column, ref_table_name, ref_column_name in indexes:%0A            ref_table = load_tables%5Bref_table_name%5D%0A            subq = select(%5Bgetattr(ref_table.c, ref_column_name)%5D)%0A            sql = utils.InsertFromSelect(table_dump, table.select().where(%0A                ~ getattr(table.c, column).in_(subq)))%0A            sql_del = table.delete().where(%0A                ~ getattr(table.c, column).in_(subq))%0A            migrate_engine.execute(sql)%0A            migrate_engine.execute(sql_del)%0A
 %0A   
@@ -2822,24 +2822,79 @@
 te_engine):%0A
+    if migrate_engine.name == 'sqlite':%0A        return%0A
     meta = M
@@ -3480,32 +3480,77 @@
 _name, column))%0A
+            with migrate_engine.begin():%0A    
             fkey
@@ -3591,24 +3591,28 @@
             
+    
 fkey.drop()%0A
@@ -3611,8 +3611,354 @@
 .drop()%0A
+        with migrate_engine.begin():%0A            # Restore data that had been dropped.%0A            table_dump_name = 'dump_' + table_name%0A            table_dump = Table(table_dump_name, meta, autoload=True)%0A            sql = utils.InsertFromSelect(table, table_dump.select())%0A            migrate_engine.execute(sql)%0A            table_dump.drop()%0A

Fix migration with fkeys