com.tesora.dve.sql.statement.ddl.alter.AddColumnAction.java Source code

Java tutorial

Introduction

Here is the source code for com.tesora.dve.sql.statement.ddl.alter.AddColumnAction.java

Source

package com.tesora.dve.sql.statement.ddl.alter;

/*
 * #%L
 * Tesora Inc.
 * Database Virtualization Engine
 * %%
 * Copyright (C) 2011 - 2014 Tesora Inc.
 * %%
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero 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 Affero General Public License for more details.
 * 
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 * #L%
 */

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang.StringUtils;

import com.tesora.dve.sql.schema.Name;
import com.tesora.dve.sql.schema.PEColumn;
import com.tesora.dve.sql.schema.PETable;
import com.tesora.dve.sql.schema.SchemaContext;
import com.tesora.dve.sql.transform.execution.CatalogModificationExecutionStep.Action;
import com.tesora.dve.sql.util.Functional;
import com.tesora.dve.sql.util.Pair;
import com.tesora.dve.sql.util.UnaryFunction;

public class AddColumnAction extends AbstractAlterColumnAction {

    private List<PEColumn> newColumns;
    private Pair<String, Name> firstOrAfterSpec;

    public AddColumnAction(List<PEColumn> columns) {
        this(columns, null);
    }

    public AddColumnAction(List<PEColumn> columns, Pair<String, Name> firstOrAfterSpec) {
        newColumns = columns;
        for (PEColumn p : newColumns)
            p.normalize();
        this.firstOrAfterSpec = firstOrAfterSpec;
    }

    public List<PEColumn> getNewColumns() {
        return newColumns;
    }

    @Override
    public AlterTableAction alterTable(SchemaContext sc, PETable tab) {
        List<PEColumn> movedCols = null;
        if (firstOrAfterSpec != null) {
            // take a first pass and update the ordinal numbers
            int ordinal = -1;
            if (StringUtils.equalsIgnoreCase(firstOrAfterSpec.getFirst(), "AFTER")) {
                PEColumn afterColumn = tab.lookup(sc,
                        firstOrAfterSpec.getSecond().getUnqualified().getUnquotedName().get());
                ordinal = afterColumn.getPosition();
            }
            movedCols = new ArrayList<PEColumn>();
            List<PEColumn> origCols = tab.getColumns(sc);
            for (PEColumn col : origCols) {
                if (col.getPosition() > ordinal) {
                    movedCols.add(col);
                }
            }

            for (PEColumn col : movedCols) {
                tab.removeColumn(sc, col);
            }
        }
        for (PEColumn nc : newColumns) {
            if (nc.getIn(sc, tab) == null) {
                PEColumn copy = (PEColumn) nc.copy(sc, null);
                tab.addColumn(sc, copy);
                // add back the columns if FIRST or AFTER was specified
                if (movedCols != null) {
                    for (PEColumn c : movedCols) {
                        tab.addColumn(sc, c);
                    }
                }
            }
        }
        return null;
    }

    @Override
    public boolean isNoop(SchemaContext sc, PETable tab) {
        // only a noop if all are a noop
        for (PEColumn nc : newColumns) {
            if (nc.getIn(sc, tab) == null) {
                return false;
            }
        }
        return true;
    }

    @Override
    public String isValid(SchemaContext sc, PETable tab) {
        if (firstOrAfterSpec != null && firstOrAfterSpec.getSecond() != null) {
            // validate the after column exists
            if (tab.lookup(sc, firstOrAfterSpec.getSecond()) == null) {
                return "Table " + tab.getName() + " does not contain column "
                        + firstOrAfterSpec.getSecond().getSQL() + " that was specified with AFTER.  Cannot add.";
            }
        }
        // only valid if any of the columns doesn't already exist
        for (PEColumn nc : newColumns) {
            if (nc.getIn(sc, tab) == null)
                return null;
        }
        return "Table " + tab.getName() + " already contains column" + (newColumns.size() > 1 ? "s " : " ")
                + Functional.join(newColumns, ", ", new UnaryFunction<String, PEColumn>() {

                    @Override
                    public String evaluate(PEColumn object) {
                        return object.getName().get();
                    }

                }) + ", cannot add";
    }

    @Override
    public AlterTableAction adapt(SchemaContext sc, PETable actual) {
        return new AddColumnAction(newColumns);
    }

    @Override
    public Action getActionKind() {
        return Action.CREATE;
    }

    @Override
    public List<PEColumn> getColumns() {
        return newColumns;
    }

    public Pair<String, Name> getFirstOrAfterSpec() {
        return firstOrAfterSpec;
    }

}