/*
* DBeaver - Universal Database Manager
* Copyright (C) 2013-2015 Denis Forveille (titou10.titou10@gmail.com)
* Copyright (C) 2010-2017 Serge Rider (serge@jkiss.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jkiss.dbeaver.ext.db2.manager;
import org.jkiss.code.Nullable;
import org.jkiss.dbeaver.DBException;
import org.jkiss.dbeaver.ext.db2.model.DB2Table;
import org.jkiss.dbeaver.ext.db2.model.DB2TableBase;
import org.jkiss.dbeaver.ext.db2.model.DB2TableColumn;
import org.jkiss.dbeaver.model.DBPEvaluationContext;
import org.jkiss.dbeaver.model.DBUtils;
import org.jkiss.dbeaver.model.edit.DBECommandContext;
import org.jkiss.dbeaver.model.edit.DBEObjectRenamer;
import org.jkiss.dbeaver.model.edit.DBEPersistAction;
import org.jkiss.dbeaver.model.impl.DBSObjectCache;
import org.jkiss.dbeaver.model.impl.edit.SQLDatabasePersistAction;
import org.jkiss.dbeaver.model.impl.sql.edit.struct.SQLTableColumnManager;
import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
import org.jkiss.dbeaver.model.struct.DBSObject;
import org.jkiss.dbeaver.utils.GeneralUtils;
import org.jkiss.utils.CommonUtils;
import java.util.List;
import java.util.Map;
/**
* DB2 Table Column Manager
*
* @author Denis Forveille
*/
public class DB2TableColumnManager extends SQLTableColumnManager<DB2TableColumn, DB2TableBase> implements DBEObjectRenamer<DB2TableColumn> {
private static final String SQL_ALTER = "ALTER TABLE %s ALTER COLUMN %s ";
private static final String SQL_COMMENT = "COMMENT ON COLUMN %s.%s IS '%s'";
private static final String SQL_REORG = "CALL SYSPROC.ADMIN_CMD('REORG TABLE %s')";
private static final String CLAUSE_SET_TYPE = " SET DATA TYPE ";
private static final String CLAUSE_SET_NULL = " SET NOT NULL";
private static final String CLAUSE_DROP_NULL = " DROP NOT NULL";
private static final String CMD_ALTER = "Alter Column";
private static final String CMD_COMMENT = "Comment on Column";
private static final String CMD_REORG = "Reorg table";
private static final String LINE_SEPARATOR = GeneralUtils.getDefaultLineSeparator();
// -----------------
// Business Contract
// -----------------
@Nullable
@Override
public DBSObjectCache<? extends DBSObject, DB2TableColumn> getObjectsCache(DB2TableColumn object)
{
return object.getParentObject().getContainer().getTableCache().getChildrenCache((DB2Table) object.getParentObject());
}
@Override
public boolean canEditObject(DB2TableColumn object)
{
// Edit is only availabe for DB2Table and not for other kinds of tables (View, MQTs, Nicknames..)
DB2TableBase db2TableBase = object.getParentObject();
if ((db2TableBase != null) & (db2TableBase.getClass().equals(DB2Table.class))) {
return true;
} else {
return false;
}
}
// ------
// Create
// ------
@Override
protected DB2TableColumn createDatabaseObject(DBRProgressMonitor monitor, DBECommandContext context, DB2TableBase parent,
Object copyFrom)
{
DB2TableColumn column = new DB2TableColumn(parent);
column.setName(getNewColumnName(monitor, context, parent));
return column;
}
// -----
// Alter
// -----
@Override
protected void addObjectModifyActions(List<DBEPersistAction> actionList, ObjectChangeCommand command)
{
DB2TableColumn db2Column = command.getObject();
boolean hasColumnChanges = false;
if (!command.getProperties().isEmpty()) {
final String deltaSQL = computeDeltaSQL(command);
if (!deltaSQL.isEmpty()) {
hasColumnChanges = true;
String sqlAlterColumn = String.format(SQL_ALTER, db2Column.getTable().getFullyQualifiedName(DBPEvaluationContext.DDL), deltaSQL);
actionList.add(new SQLDatabasePersistAction(CMD_ALTER, sqlAlterColumn));
}
}
// Comment
DBEPersistAction commentAction = buildCommentAction(db2Column);
if (commentAction != null) {
actionList.add(commentAction);
}
if (hasColumnChanges) {
// Be Safe, Add a reorg action
actionList.add(buildReorgAction(db2Column));
}
}
// -------
// Helpers
// -------
private String computeDeltaSQL(ObjectChangeCommand command)
{
if (command.getProperties().isEmpty() ||
(command.getProperties().size() == 1 && command.getProperty("description") != null))
{
return "";
}
/*
if (log.isDebugEnabled()) {
for (Map.Entry<Object, Object> entry : command.getProperties().entrySet()) {
log.debug(entry.getKey() + "=" + entry.getValue());
}
}
*/
DB2TableColumn column = command.getObject();
StringBuilder sb = new StringBuilder(128);
sb.append(column.getName());
Boolean required = (Boolean) command.getProperty("required");
if (required != null) {
sb.append(LINE_SEPARATOR);
if (required) {
sb.append(CLAUSE_SET_NULL);
} else {
sb.append(CLAUSE_DROP_NULL);
}
}
String type = (String) command.getProperty("type");
if (type != null) {
sb.append(LINE_SEPARATOR);
sb.append(CLAUSE_SET_TYPE);
sb.append(type);
}
return sb.toString();
}
private DBEPersistAction buildCommentAction(DB2TableColumn db2Column)
{
if (CommonUtils.isNotEmpty(db2Column.getDescription())) {
String tableName = db2Column.getTable().getFullyQualifiedName(DBPEvaluationContext.DDL);
String columnName = db2Column.getName();
String comment = db2Column.getDescription();
String commentSQL = String.format(SQL_COMMENT, tableName, columnName, comment);
return new SQLDatabasePersistAction(CMD_COMMENT, commentSQL);
} else {
return null;
}
}
private DBEPersistAction buildReorgAction(DB2TableColumn db2Column)
{
String tableName = db2Column.getTable().getFullyQualifiedName(DBPEvaluationContext.DDL);
String reorgSQL = String.format(SQL_REORG, tableName);
return new SQLDatabasePersistAction(CMD_REORG, reorgSQL);
}
@Override
public void renameObject(DBECommandContext commandContext, DB2TableColumn object, String newName) throws DBException {
processObjectRename(commandContext, object, newName);
}
@Override
protected void addObjectRenameActions(List<DBEPersistAction> actions, ObjectRenameCommand command)
{
final DB2TableColumn column = command.getObject();
actions.add(
new SQLDatabasePersistAction(
"Rename column",
"ALTER TABLE " + column.getTable().getFullyQualifiedName(DBPEvaluationContext.DDL) + " RENAME COLUMN " +
DBUtils.getQuotedIdentifier(column.getDataSource(), command.getOldName()) + " TO " + DBUtils.getQuotedIdentifier(column.getDataSource(), command.getNewName()))
);
}
}