# Copyright (c) 2015 EMC Corporation
# All Rights Reserved.
#
#    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 sqlalchemy import Column, DateTime, MetaData, String, Table


def upgrade(migrate_engine):
    meta = MetaData()
    meta.bind = migrate_engine

    backups = Table('backups', meta, autoload=True)
    snapshot_id = Column('snapshot_id', String(length=36))
    data_timestamp = Column('data_timestamp', DateTime)

    backups.create_column(snapshot_id)
    backups.update().values(snapshot_id=None).execute()

    backups.create_column(data_timestamp)
    backups.update().values(data_timestamp=None).execute()

    # Copy existing created_at timestamp to data_timestamp
    # in the backups table.
    backups_list = list(backups.select().execute())
    for backup in backups_list:
        backup_id = backup.id
        backups.update().\
            where(backups.c.id == backup_id).\
            values(data_timestamp=backup.created_at).execute()

# Copyright (c) 2015 EMC Corporation
# All Rights Reserved.
#
#    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 sqlalchemy import Column, DateTime, MetaData, String, Table


def upgrade(migrate_engine):
    meta = MetaData()
    meta.bind = migrate_engine

    backups = Table('backups', meta, autoload=True)
    snapshot_id = Column('snapshot_id', String(length=36))
    data_timestamp = Column('data_timestamp', DateTime)

    backups.create_column(snapshot_id)

    backups.create_column(data_timestamp)
    backups.update().values(data_timestamp=backups.c.created_at).execute()

Fix race conditions in migration 061
Fix race conditions in migration 061

Migration 061 is supposed to add new `data_timestamp` field and populate
it with value of `created_at` column. This was done by selecting all the
backups and doing updates one-by-one. As it wasn't done in transaction
solution was prone to race condition when a new backup is added while
running the migration. This means that this migration could cause
problems when running in live environment. With blueprint
online-schema-upgrades we want to make Cinder able to perform migrations
live.

A solution is to change this statement to a single DB query which
updates all the rows. This commit also removes unnecessary update to
snapshot_id added there. As this column is nullable it will by default
be NULL, so there's no need to set it manually to that value.

As before and after this commit the migration does logically the same,
this should be safe even if someone is doing inter-release deployments.

An alternative would be to simply add transaction to the update step in
the migration, but that would effectively lock the table for longer
period of time than atomic one-query update.

Closes-Bug: 1530358
Change-Id: Ib8733c096a3dbe2bad00beaf5734936ffcddda33
