package com.tesora.dve.sql.statement.ddl;
/*
* #%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.Collections;
import java.util.List;
import com.tesora.dve.common.catalog.CatalogDAO;
import com.tesora.dve.common.catalog.CatalogEntity;
import com.tesora.dve.common.catalog.Container;
import com.tesora.dve.common.catalog.UserDatabase;
import com.tesora.dve.common.catalog.UserTable;
import com.tesora.dve.exceptions.PEException;
import com.tesora.dve.lockmanager.LockType;
import com.tesora.dve.sql.SchemaException;
import com.tesora.dve.sql.ParserException.Pass;
import com.tesora.dve.sql.schema.DatabaseLock;
import com.tesora.dve.sql.schema.PEDatabase;
import com.tesora.dve.sql.schema.SchemaContext;
import com.tesora.dve.sql.statement.StatementType;
public class PEDropDatabaseStatement extends
PEDropStatement<PEDatabase, UserDatabase> {
private List<CatalogEntity> updates;
private List<CatalogEntity> deletes;
public PEDropDatabaseStatement(PEDatabase peds, String tag) {
super(PEDatabase.class, null, false, peds, tag);
updates = null;
deletes = null;
}
@SuppressWarnings("unchecked")
private void compute(SchemaContext sc) {
if (deletes != null) return;
DatabaseLock dl = new DatabaseLock("drop database",(PEDatabase)getTarget());
sc.getConnection().acquireLock(dl, LockType.EXCLUSIVE);
// for all tables in database that are base tables for a container:
// for all such containers:
// if all tables in container are in the target database - ok
// update container to remove base table
// otherwise - error
//
CatalogDAO c = sc.getCatalog().getDAO();
try {
UserDatabase udb = getTarget().getPersistent(sc);
List<UserTable> baseTables = c.findBaseTables(udb);
deletes = new ArrayList<CatalogEntity>();
deletes.add(udb);
if (baseTables.isEmpty()) {
updates = Collections.EMPTY_LIST;
} else {
updates = new ArrayList<CatalogEntity>();
for(UserTable ut : baseTables) {
Container ofContainer = ut.getContainer();
List<UserDatabase> dbsOf = c.findDatabasesWithin(ofContainer);
if (dbsOf.size() > 1)
throw new SchemaException(Pass.PLANNER, "Unable to drop database "
+ getTarget().getName().getSQL()
+ " because table " + ut.getName()
+ " is a container base table for container " + ofContainer.getName());
else {
// remove the base table from the container
ofContainer.setBaseTable(null);
updates.add(ofContainer);
}
}
}
} catch (PEException pe) {
throw new SchemaException(Pass.PLANNER, "Unable to compute drop set for drop database",pe);
}
}
@Override
public List<CatalogEntity> getCatalogObjects(SchemaContext sc) throws PEException {
compute(sc);
return updates;
}
@Override
public List<CatalogEntity> getDeleteObjects(SchemaContext sc) throws PEException {
compute(sc);
return deletes;
}
@Override
public StatementType getStatementType() {
return StatementType.DROP_DB;
}
}