bool BaseMigrationTableService::removeMigration(const QString &migrationName,
                                                const CommandExecution::CommandExecutionContext &context) const
{
    const QString versionTableName = context.migrationConfig().migrationVersionTableName;
    const QString query =
            QString("DELETE FROM %1 WHERE version = %2")
            .arg(context.helperRepository().quoteService().quoteTableName(versionTableName))
            .arg(context.helperRepository().quoteService().quoteString(migrationName));
    ::qDebug() << "removing entry to version table. complete query looks like:";
    ::qDebug() << query;
    QSqlQuery sqlQuery = context.database().exec(query);
    if (sqlQuery.lastError().isValid()) {
        ::qDebug() << Q_FUNC_INFO << sqlQuery.lastError().text();
        return false;
    }
    return true;
}
bool BaseSqlDropTableService::execute(const Commands::ConstCommandPtr &command,
                                      CommandExecution::CommandExecutionContext &context) const
{
    QSharedPointer<const Commands::DropTable> dropTable(command.staticCast<const Commands::DropTable>());
    Q_ASSERT(dropTable);

    const Structure::Table originalTable( context.helperRepository().sqlStructureService().getTableDefinition(dropTable->tableName(), context.database()) );

    bool success = execute(*dropTable, context);

    if (success) {
        context.setUndoCommand(Commands::CommandPtr(new Commands::CreateTable(originalTable)));
    }
    return success;
}
bool SqliteDropColumnService::execute(const Commands::ConstCommandPtr &command,
                                      CommandExecution::CommandExecutionContext &context) const
{
    QSharedPointer<const Commands::DropColumn> dropColumn(command.staticCast<const Commands::DropColumn>());

    Structure::Table table( context.helperRepository().sqlStructureService().getTableDefinition(dropColumn->tableName(), context.database()) );
    Structure::Table::Builder alteredTable(dropColumn->tableName());
    const Structure::Column* originalColumn = Q_NULLPTR;
    foreach (const Structure::Column &column, table.columns()) {
        if (column.name() == dropColumn->columnName()) {
            originalColumn = &column;
        } else {
            alteredTable << column;
        }
    }
    if (!originalColumn) {
        ::qWarning() << "Column not found" << dropColumn->tableName() << dropColumn->columnName();
        return false;
    }

    QString tempTableName = QString("%1%2").arg(context.migrationConfig().temporaryTablePrefix, dropColumn->tableName());

    bool success = BaseSqlRenameTableService::execute(Commands::RenameTable(dropColumn->tableName(), tempTableName), context);
    if (!success)
        return false;

    success = BaseSqlCreateTableService::execute(Commands::CreateTable(alteredTable), context);
    if (!success)
        return false;

    const QString copyQuery =
            QString("INSERT INTO %1 SELECT %2 FROM %3")
            .arg(table.name())
            .arg(table.columnNames().join(", "))
            .arg(tempTableName);
    success = CommandExecution::BaseCommandExecutionService::executeQuery(copyQuery, context);
    if (!success)
        return false;

    success = BaseSqlDropTableService::execute(Commands::DropTable(tempTableName), context);

    if (success && context.isUndoUsed()) {
        context.setUndoCommand(Commands::CommandPtr(new Commands::AddColumn(*originalColumn, dropColumn->tableName())));
    }
    return success;
}
QStringList BaseMigrationTableService::migrationList(const CommandExecution::CommandExecutionContext &context) const
{
    const QString versionTableName = context.migrationConfig().migrationVersionTableName;
    QSqlQuery sqlQuery = context.database().exec(
                QString("SELECT version FROM %1")
                .arg(context.helperRepository().quoteService().quoteTableName(versionTableName)));

    QStringList migrationList;
    if (sqlQuery.lastError().isValid()) {
        ::qDebug() << Q_FUNC_INFO << sqlQuery.lastError().text();
    } else {
        while (sqlQuery.next()) {
            migrationList << sqlQuery.value(0).toString();
        }
    }
    return migrationList;
}
bool MysqlRenameColumnService::execute(const Commands::ConstCommandPtr &command,
                                       CommandExecution::CommandExecutionContext &context) const
{
    QSharedPointer<const Commands::RenameColumn> renameColumn(command.staticCast<const Commands::RenameColumn>());
    Q_ASSERT(renameColumn);

    const Structure::Column originalColumn( context.helperRepository().sqlStructureService()
                                            .getTableDefinition(renameColumn->tableName(), context.database())
                                            .fetchColumnByName(renameColumn->oldName()) );
    if (!originalColumn.isValid()) {
        ::qWarning() << "could not find column" << renameColumn->tableName() << renameColumn->oldName();
        return false;
    }

    bool success = execute(*renameColumn, originalColumn, context);

    if (success && context.isUndoUsed()) {
        context.setUndoCommand(renameColumn->reverse());
    }
    return success;
}