Skip to content
Table.java 7.37 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.
 */
package it.inaf.ia2.tsm;

import it.inaf.ia2.tsm.datalayer.DBBroker;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.TreeMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * The main implementation of {@link Table}.
 *
 * @author Sonia Zorba {@literal <zorba at oats.inaf.it>}
 */
public class Table extends ChildEntity<Schema> implements EntitiesContainer<Column> {

    public final static String SCHEMA_NAME_KEY = "schema_name";
    public final static String TABLE_NAME_KEY = "table_name";
    public final static String TABLE_TYPE_KEY = "table_type";

    private static final long serialVersionUID = 8265331530960896871L;
    private static final Logger LOG = LoggerFactory.getLogger(Table.class);

    private Map<String, Map<String, Object>> columnsMetadata;
    private Map<String, Column> columns;

    private String simpleName;
    private Schema parentSchema;

    private Table() {
        // for serialization
        super();
    }

    protected Table(TapSchema tapSchema, Schema schema, String tableSimpleName) throws SQLException {
        super(tapSchema, tapSchema.getTableModel(TapSchema.TABLES_TABLE), schema.getTableMetadata(tableSimpleName));

        parentSchema = schema;
        this.simpleName = tableSimpleName;

        columns = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);

        DBBroker broker = tapSchema.getDBBroker(schema.getName());
        columnsMetadata = broker.getAllColumnsMetadata(schema.getName(), tableSimpleName);
        for (Map.Entry<String, Map<String, Object>> entry : columnsMetadata.entrySet()) {
            // Adding table names to columns metadata
            entry.getValue().put(Column.TABLE_NAME_KEY, schema.getName() + "." + tableSimpleName);
            // Initializing columns map
            columns.put(entry.getKey(), null);
        }

        setStatus(Status.LOADED);
    }

    /**
     * Only the table name.
     */
    @Override
    public String getName() {
        return simpleName;
    }

    /**
     * {@code schema_name.table_name}.
     */
    public String getCompleteName() {
        return getValue(TABLE_NAME_KEY, String.class);
    }

    /**
     * {@inheritDoc }
     */
    @Override
    public Column addChild(String columnName) {
        String tableCompleteName = getCompleteName();

        LOG.debug("Adding column {} into table {}", columnName, tableCompleteName);

        if (!columns.containsKey(columnName)) {
            return null;
        } else {
            Column column = columns.get(columnName);
            if (column == null) {
                column = new Column(tapSchema, this, columnName);
                columns.put(columnName, column);
                column.setStatus(Status.ADDED_NOT_PERSISTED);
            } else {
                switch (column.getStatus()) {
                    case REMOVED_NOT_PERSISTED: // undo removal
                        column.setStatus(Status.ADDED_NOT_PERSISTED);
                        break;
                    case TO_REMOVE: // undo removal
                        column.setStatus(Status.ADDED_PERSISTED);
                        break;
                    default:
                        throw new IllegalArgumentException("Cannot add column " + columnName + " in table " + tableCompleteName + ". Invalid column status: " + column.getStatus());
                }
            }

            tapSchema.checkKeys();

            return column;
        }
    }

    /**
     * {@inheritDoc }
     */
    @Override
    public void removeChild(String columnName) {
        String tableCompleteName = getCompleteName();

        LOG.debug("Removing column {} from table {}", columnName, tableCompleteName);

        if (!columns.containsKey(columnName)) {
            throw new IllegalArgumentException("Column " + columnName + " doesn't exists in table " + tableCompleteName);
        }

        Column column = columns.get(columnName);

        switch (column.getStatus()) {
            case ADDED_NOT_PERSISTED:
                column.setStatus(Status.REMOVED_NOT_PERSISTED);
                break;
            case ADDED_PERSISTED:
                column.setStatus(Status.TO_REMOVE);
                break;
            default:
                throw new IllegalArgumentException("Cannot remove column " + columnName + " in table " + tableCompleteName + ". Invalid column status: " + column.getStatus());
        }

        tapSchema.checkKeys();
    }

    /**
     * {@inheritDoc }
     */
    @Override
    public Column getChild(String childName, Status... statuses) {
        return TSMUtil.getChild(columns, childName, statuses);
    }

    /**
     * {@inheritDoc }
     */
    @Override
    public List<Column> getChildren(Status... statuses) {
        return TSMUtil.getChildrenByStatus(columns.values(), statuses);
    }

    /**
     * {@inheritDoc }
     */
    @Override
    public List<String> getAddableChildrenNames() {
        return TSMUtil.getAddableChildrenNames(columns);
    }

    @Override
    public List<Column> getAddedChildren() {
        return getChildren(Status.ADDED_PERSISTED, Status.ADDED_NOT_PERSISTED);
    }

    @Override
    public List<Column> getAddedOrRemovedChildren() {
        return getChildren(Status.ADDED_PERSISTED, Status.ADDED_NOT_PERSISTED, Status.TO_REMOVE, Status.REMOVED_NOT_PERSISTED);
    }

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 29 * hash + Objects.hashCode(this.getCompleteName());
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final Table other = (Table) obj;
        if (!Objects.equals(this.getCompleteName(), other.getCompleteName())) {
            return false;
        }
        return true;
    }

    protected void afterUpdate() {
        for (Column column : columns.values()) {
            if (column.getStatus() == Status.ADDED_NOT_PERSISTED) {
                column.setStatus(Status.ADDED_PERSISTED);
            } else if (column.getStatus() != Status.ADDED_PERSISTED) {
                column.setStatus(Status.LOADED);
            }
        }
    }

    @Override
    public Schema getParent() {
        return parentSchema;
    }

    public Map<String, Object> getColumnMetadata(String columnName) {
        return columnsMetadata.get(columnName);
    }
}