Skip to content
TapSchemaMender.java 6.51 KiB
Newer Older
/*
 * _____________________________________________________________________________
 * 
 * INAF - OATS National Institute for Astrophysics - Astronomical Observatory of
 * Trieste INAF - IA2 Italian Center for Astronomical Archives
 * _____________________________________________________________________________
 * 
 * Copyright (C) 2017 Istituto Nazionale di Astrofisica
 * 
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License Version 3 as published by the
 * Free Software Foundation.
 * 
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 * details.
 * 
 * You should have received a copy of the GNU General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc., 51
 * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */
package it.inaf.ia2.tsm;

import it.inaf.ia2.tsm.datalayer.DBBroker;
import it.inaf.ia2.tsm.model.ColumnModel;
import it.inaf.ia2.tsm.model.SchemaModel;
import it.inaf.ia2.tsm.model.TableModel;
import java.sql.SQLException;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * This fixes TAP_SCHEMA inconsistencies.
 *
 * @author Sonia Zorba {@literal <zorba at oats.inaf.it>}
 */
public class TapSchemaMender {

    private final TapSchema tapSchema;
    private final ConsistencyChecks consistencyChecks;

    public TapSchemaMender(TapSchema tapSchema) {
        this.tapSchema = tapSchema;
        consistencyChecks = tapSchema.getConsistencyChecks();
    }

    public static void amendTapSchema(TapSchema tapSchema) throws SQLException {
        new TapSchemaMender(tapSchema).amendTapSchema();
    }

    private void amendTapSchema() throws SQLException {

        fixObscore();
        createMissingTables();
        createMissingColumns();
        fixDataTypes();
        deleteUnexistingEntities();
        addUnaddedTables();
        addUnaddedColumns();
        fixInconsistentValues();
    }

    private void fixObscore() throws SQLException {

        SchemaModel ivoaSchemaModel = tapSchema.getIvoaSchemaModel();

        if (tapSchema.isHasObscore()) {
            if (consistencyChecks.isMissingObscore()) {
                tapSchema.createAndAddIvoaSchema();
            }
            if (consistencyChecks.isMissingObscore()
                    || consistencyChecks.isObscoreToAdd()) {
                tapSchema.addEntireSchema(ivoaSchemaModel.getName());
                tapSchema.fillColumnsProperties(ivoaSchemaModel);
            }
        }
    }

    private void createMissingTables() throws SQLException {
        for (Map.Entry<String, Set<String>> entry : consistencyChecks.getMissingTables().entrySet()) {
            String schemaName = entry.getKey();
            DBBroker broker = tapSchema.getDBBroker(schemaName);
            for (String tableName : entry.getValue()) {
                SchemaModel schemaModel = schemaName.equals(tapSchema.getName())
                        ? tapSchema.getTapSchemaModel() : tapSchema.getIvoaSchemaModel();
                TableModel tableModel = schemaModel.getTable(tableName);
                broker.createTable(schemaName, tableModel);
            }
        }
    }

    private void createMissingColumns() throws SQLException {
        for (Map.Entry<ColumnHolder, ColumnModel> entry : consistencyChecks.getMissingColumns().entrySet()) {
            ColumnHolder columnHolder = entry.getKey();
            ColumnModel columnModel = entry.getValue();
            DBBroker broker = tapSchema.getDBBroker(columnHolder.getSchemaName());
            broker.addColumn(columnHolder, columnModel);
        }
    }

    private void fixDataTypes() throws SQLException {
        for (WrongDataType wrongDataType : consistencyChecks.getWrongDataTypes()) {
            ColumnHolder columnHolder = wrongDataType.getColumnHolder();
            DBBroker broker = tapSchema.getDBBroker(columnHolder.getSchemaName());
            broker.alterDataType(columnHolder.getSchemaName(),
                    columnHolder.getTableName(), columnHolder.getColumnName(),
                    wrongDataType.getAdqlCorrectDataType(), wrongDataType.getSize());
        }
    }

    private void deleteUnexistingEntities() throws SQLException {
        String tapSchemaName = tapSchema.getName();
        DBBroker tapSchemaDBBroker = tapSchema.getTapSchemaDBBroker();

        Set<String> keysToRemoveIds = new HashSet<>();

        for (String schema : consistencyChecks.getUnexisingSchemas()) {
            keysToRemoveIds.addAll(tapSchemaDBBroker.getKeysToRemove(tapSchemaName, schema));
        }
        for (String table : consistencyChecks.getUnexisingTables()) {
            keysToRemoveIds.addAll(tapSchemaDBBroker.getKeysToRemove(tapSchemaName, table));
        }
        for (ColumnHolder unexistingColumn : consistencyChecks.getUnexisingColumns()) {
            keysToRemoveIds.addAll(tapSchemaDBBroker.getKeysToRemoveFromUnexistingColumn(tapSchemaName, unexistingColumn));
        }
        for (KeyHolder unexistingKey : consistencyChecks.getUnexistingKeys()) {
            keysToRemoveIds.add(unexistingKey.getKeyId());
        }

        tapSchemaDBBroker.deleteUnexistingEntities(tapSchemaName, consistencyChecks, keysToRemoveIds);
    }

    private void addUnaddedTables() throws SQLException {
        for (Map.Entry<String, Set<String>> entry : consistencyChecks.getTablesToAdd().entrySet()) {
            String schemaName = entry.getKey();
            Schema schema = tapSchema.getChild(schemaName);
            for (String tableName : entry.getValue()) {
                schema.addChild(tableName);
            }
        }
    }

    private void addUnaddedColumns() throws SQLException {
        for (ColumnHolder columnHolder : consistencyChecks.getColumnsToAdd()) {
            Schema schema = tapSchema.getChild(columnHolder.getSchemaName());
            Table table = schema.getChild(columnHolder.getTableName());
            table.addChild(columnHolder.getColumnName());
        }
    }

    private void fixInconsistentValues() throws SQLException {
        for (InconsistentColumnProperty inconsistency : consistencyChecks.getInconsistencies()) {
            tapSchema.getTapSchemaDBBroker().updateTapSchemaColumnValue(tapSchema.getRealName(),
                    inconsistency.getTableCompleteName(), inconsistency.getColumnName(),
                    inconsistency.getKey(), inconsistency.getCorrectValue());
        }
    }
}