Skip to content
UpdateOperations.java 9.86 KiB
Newer Older
/* 
 * _____________________________________________________________________________
 * 
 * INAF - OATS National Institute for Astrophysics - Astronomical Observatory of
 * Trieste INAF - IA2 Italian Center for Astronomical Archives
 * _____________________________________________________________________________
 * 
 * Copyright (C) 2016 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.
 */
import java.util.ArrayList;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Models the list of operations that have to be performed by the
 * {@link it.inaf.ia2.tsm.TapSchema#save()} method, in terms of adding, updating
 * or removing {@link it.inaf.ia2.tsm.TapSchemaEntity} entities. Could also be
 * used stand-alone to obtain a preview of the operations that will be performed
 * on the database.
 *
 * @author Sonia Zorba {@literal <zorba at oats.inaf.it>}
 */
public class UpdateOperations {

    private static final Logger LOG = LoggerFactory.getLogger(UpdateOperations.class);

    private final List<Schema> schemasToRemove;
    private final List<Schema> schemasToAdd;
    private final List<Schema> schemasToUpdate;
    private final List<Schema> schemasToClean; // REMOVED_NOT_PERSISTED
    private final List<Table> tablesToRemove;
    private final List<Table> tablesToAdd;
    private final List<Table> tablesToUpdate;
    private final List<Table> tablesToClean; // REMOVED_NOT_PERSISTED
    private final List<Column> columnsToRemove;
    private final List<Column> columnsToAdd;
    private final List<Column> columnsToUpdate;
    private final List<Column> columnsToClean; // REMOVED_NOT_PERSISTED
    private final List<Key> keysToRemove;
    private final List<Key> keysToAdd;
    private final List<Key> keysToUpdate;

    private void manageAddedNotPersistedTable(Table table) {
        tablesToAdd.add(table);

        // children columns can have only the following status:
        // ADDED_NOT_PERSISTED, REMOVED_NOT_PERSISTED, LOADED
        columnsToAdd.addAll(table.getChildren(Status.ADDED_NOT_PERSISTED));
        for (Column column : table.getChildren(Status.REMOVED_NOT_PERSISTED)) {
            columnsToClean.add(column);
        }
    }

    public UpdateOperations(TapSchema tapSchema) {
        schemasToRemove = new ArrayList<>();
        schemasToAdd = new ArrayList<>();
        schemasToUpdate = new ArrayList<>();
        tablesToRemove = new ArrayList<>();
        tablesToAdd = new ArrayList<>();
        tablesToUpdate = new ArrayList<>();
        columnsToRemove = new ArrayList<>();
        columnsToAdd = new ArrayList<>();
        columnsToUpdate = new ArrayList<>();
        keysToRemove = new ArrayList<>();
        keysToAdd = new ArrayList<>();
        keysToUpdate = new ArrayList<>();

        for (Key key : tapSchema.getAllKeys()) {
            if (key.isVisible()) {
                String originalKeyId = key.getOriginalValue(Key.ID_KEY, String.class);
                if (originalKeyId == null) {
                    keysToAdd.add(key);
                } else if (key.isChanged()) {
                    keysToUpdate.add(key);
            } else if (key.getId() != null) {
                keysToRemove.add(key);
            }
        }

        for (Schema schema : tapSchema.getChildren()) {

            switch (schema.getStatus()) {
                case ADDED_NOT_PERSISTED:

                    schemasToAdd.add(schema);

                    for (Table table : schema.getChildren()) {

                        // children tables can have the following status:
                        // ADDED_NOT_PERSISTED, REMOVED_NOT_PERSISTED, LOADED
                        switch (table.getStatus()) {
                            case ADDED_NOT_PERSISTED:
                                manageAddedNotPersistedTable(table);
                                break;
                            case REMOVED_NOT_PERSISTED:
                                tablesToClean.add(table);
                                break;
                        }
                    }

                    break;

                case ADDED_PERSISTED:

                    if (schema.isChanged()) {
                        schemasToUpdate.add(schema);
                    }

                    // children tables can have any status!
                    for (Table table : schema.getChildren()) {
                        switch (table.getStatus()) {
                            case ADDED_NOT_PERSISTED:
                                manageAddedNotPersistedTable(table);
                                break;
                            case ADDED_PERSISTED:
                                if (table.isChanged()) {
                                    tablesToUpdate.add(table);
                                }
                                // children columns can have any status!
                                for (Column column : table.getChildren()) {
                                    switch (column.getStatus()) {
                                        case ADDED_NOT_PERSISTED:
                                            columnsToAdd.add(column);
                                            break;
                                        case ADDED_PERSISTED:
                                            if (column.isChanged()) {
                                                columnsToUpdate.add(column);
                                            }
                                            break;
                                        case TO_REMOVE:
                                            columnsToRemove.add(column);
                                            break;
                                        case REMOVED_NOT_PERSISTED:
                                            columnsToClean.add(column);
                                    }
                                }
                                break;
                            case TO_REMOVE:
                                tablesToRemove.add(table);
                                for (Column column : table.getChildren()) {
                                    if (column.getStatus() == Status.ADDED_PERSISTED) {
                                        columnsToRemove.add(column);
                                    }
                                }
                                break;
                            case REMOVED_NOT_PERSISTED:
                                tablesToClean.add(table);
                                break;
                        }
                    }

                    break;

                case TO_REMOVE:

                    schemasToRemove.add(schema);
                    for (Table table : schema.getChildren()) {
                        if (table.getStatus() == Status.ADDED_PERSISTED) {
                            tablesToRemove.add(table);
                            for (Column column : table.getChildren()) {
                                if (column.getStatus() == Status.ADDED_PERSISTED) {
                                    columnsToRemove.add(column);
                                }
                            }
                        }
                    }

                    break;

                case REMOVED_NOT_PERSISTED:
                    schemasToClean.add(schema);
                    break;
            }
        }
    }

    public List<Schema> getSchemasToRemove() {
        return schemasToRemove;
    }

    public List<Schema> getSchemasToAdd() {
        return schemasToAdd;
    }

    public List<Schema> getSchemasToUpdate() {
        return schemasToUpdate;
    }

    public List<Schema> getSchemasToClean() {
        return schemasToClean;
    }

    public List<Table> getTablesToRemove() {
        return tablesToRemove;
    }

    public List<Table> getTablesToAdd() {
        return tablesToAdd;
    }

    public List<Table> getTablesToUpdate() {
        return tablesToUpdate;
    }

    public List<Table> getTablesToClean() {
        return tablesToClean;
    }

    public List<Column> getColumnsToRemove() {
        return columnsToRemove;
    }

    public List<Column> getColumnsToAdd() {
        return columnsToAdd;
    }

    public List<Column> getColumnsToUpdate() {
        return columnsToUpdate;
    }

    public List<Column> getColumnsToClean() {
        return columnsToClean;
    }

    public List<Key> getKeysToRemove() {
        return keysToRemove;
    }

    public List<Key> getKeysToAdd() {
        return keysToAdd;
    }

    public List<Key> getKeysToUpdate() {
        return keysToUpdate;
    }

    public boolean getHasEntitiesToAdd() {
        return !(schemasToAdd.isEmpty() && tablesToAdd.isEmpty() && columnsToAdd.isEmpty() && keysToAdd.isEmpty());
    }

    public boolean getHasEntitiesToRemove() {
        return !(schemasToRemove.isEmpty() && tablesToRemove.isEmpty() && columnsToRemove.isEmpty() && keysToRemove.isEmpty());
    }

    public boolean getHasEntitiesToUpdate() {
        return !(schemasToUpdate.isEmpty() && tablesToUpdate.isEmpty() && columnsToUpdate.isEmpty() && keysToUpdate.isEmpty());
    }

    public boolean getHasOperations() {
        return getHasEntitiesToAdd() || getHasEntitiesToRemove() || getHasEntitiesToUpdate();
    }
}