/*
* DBeaver - Universal Database Manager
* Copyright (C) 2010-2017 Serge Rider (serge@jkiss.org)
* Copyright (C) 2011-2012 Eugene Fradkin (eugene.fradkin@gmail.com)
*
* 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.mysql.edit;
import org.jkiss.code.Nullable;
import org.jkiss.dbeaver.DBException;
import org.jkiss.dbeaver.ext.mysql.MySQLConstants;
import org.jkiss.dbeaver.ext.mysql.model.MySQLTableBase;
import org.jkiss.dbeaver.ext.mysql.model.MySQLTableColumn;
import org.jkiss.dbeaver.model.DBPDataKind;
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.DBEObjectReorderer;
import org.jkiss.dbeaver.model.edit.DBEPersistAction;
import org.jkiss.dbeaver.model.impl.DBSObjectCache;
import org.jkiss.dbeaver.model.impl.edit.DBECommandAbstract;
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.sql.SQLUtils;
import org.jkiss.dbeaver.model.struct.DBSDataType;
import org.jkiss.dbeaver.model.struct.DBSObject;
import org.jkiss.dbeaver.ui.UITask;
import org.jkiss.dbeaver.ui.editors.object.struct.AttributeEditPage;
import org.jkiss.utils.CommonUtils;
import java.sql.Types;
import java.util.List;
import java.util.Locale;
/**
* MySQL table column manager
*/
public class MySQLTableColumnManager extends SQLTableColumnManager<MySQLTableColumn, MySQLTableBase>
implements DBEObjectRenamer<MySQLTableColumn>, DBEObjectReorderer<MySQLTableColumn>
{
protected final ColumnModifier<MySQLTableColumn> MySQLDataTypeModifier = new ColumnModifier<MySQLTableColumn>() {
@Override
public void appendModifier(MySQLTableColumn column, StringBuilder sql, DBECommandAbstract<MySQLTableColumn> command) {
sql.append(' ').append(column.getFullTypeName());
}
};
protected final ColumnModifier<MySQLTableColumn> CharsetModifier = new ColumnModifier<MySQLTableColumn>() {
@Override
public void appendModifier(MySQLTableColumn column, StringBuilder sql, DBECommandAbstract<MySQLTableColumn> command) {
if (column.getCharset() != null) {
sql.append(" CHARACTER SET ").append(column.getCharset().getName());
}
}
};
protected final ColumnModifier<MySQLTableColumn> CollationModifier = new ColumnModifier<MySQLTableColumn>() {
@Override
public void appendModifier(MySQLTableColumn column, StringBuilder sql, DBECommandAbstract<MySQLTableColumn> command) {
if (column.getCollation() != null) {
sql.append(" COLLATE ").append(column.getCollation().getName());
}
}
};
@Nullable
@Override
public DBSObjectCache<? extends DBSObject, MySQLTableColumn> getObjectsCache(MySQLTableColumn object)
{
return object.getParentObject().getContainer().getTableCache().getChildrenCache(object.getParentObject());
}
protected ColumnModifier[] getSupportedModifiers(MySQLTableColumn column)
{
return new ColumnModifier[] {MySQLDataTypeModifier, CharsetModifier, CollationModifier, DefaultModifier, NullNotNullModifier};
}
@Override
public StringBuilder getNestedDeclaration(MySQLTableBase owner, DBECommandAbstract<MySQLTableColumn> command)
{
StringBuilder decl = super.getNestedDeclaration(owner, command);
final MySQLTableColumn column = command.getObject();
if (!CommonUtils.isEmpty(column.getExtraInfo())) {
decl.append(" ").append(column.getExtraInfo()); //$NON-NLS-1$
}
if (column.isAutoGenerated() &&
(CommonUtils.isEmpty(column.getExtraInfo()) || !column.getExtraInfo().toLowerCase(Locale.ENGLISH).contains(MySQLConstants.EXTRA_AUTO_INCREMENT)))
{
decl.append(" AUTO_INCREMENT"); //$NON-NLS-1$
}
if (!CommonUtils.isEmpty(column.getComment())) {
decl.append(" COMMENT ").append(SQLUtils.quoteString(column.getComment())); //$NON-NLS-1$ //$NON-NLS-2$
}
return decl;
}
@Override
protected MySQLTableColumn createDatabaseObject(final DBRProgressMonitor monitor, final DBECommandContext context, final MySQLTableBase parent, Object copyFrom)
{
return new UITask<MySQLTableColumn>() {
@Override
protected MySQLTableColumn runTask() {
DBSDataType columnType = findBestDataType(parent.getDataSource(), "varchar"); //$NON-NLS-1$
final MySQLTableColumn column = new MySQLTableColumn(parent);
column.setName(getNewColumnName(monitor, context, parent));
final String typeName = columnType == null ? "integer" : columnType.getName().toLowerCase();
column.setTypeName(typeName); //$NON-NLS-1$
column.setMaxLength(columnType != null && columnType.getDataKind() == DBPDataKind.STRING ? 100 : 0);
column.setValueType(columnType == null ? Types.INTEGER : columnType.getTypeID());
column.setOrdinalPosition(parent.getCachedAttributes().size() + 1);
column.setFullTypeName(DBUtils.getFullTypeName(column));
AttributeEditPage page = new AttributeEditPage(null, column);
if (!page.edit()) {
return null;
}
return column;
}
}.execute();
}
@Override
protected void addObjectModifyActions(List<DBEPersistAction> actionList, ObjectChangeCommand command)
{
final MySQLTableColumn column = command.getObject();
actionList.add(
new SQLDatabasePersistAction(
"Modify column",
"ALTER TABLE " + column.getTable().getFullyQualifiedName(DBPEvaluationContext.DDL) + " MODIFY COLUMN " + getNestedDeclaration(column.getTable(), command))); //$NON-NLS-1$ //$NON-NLS-2$
}
@Override
public void renameObject(DBECommandContext commandContext, MySQLTableColumn object, String newName) throws DBException {
processObjectRename(commandContext, object, newName);
}
@Override
protected void addObjectRenameActions(List<DBEPersistAction> actions, ObjectRenameCommand command)
{
final MySQLTableColumn column = command.getObject();
actions.add(
new SQLDatabasePersistAction(
"Rename column",
"ALTER TABLE " + column.getTable().getFullyQualifiedName(DBPEvaluationContext.DDL) + " CHANGE " +
DBUtils.getQuotedIdentifier(column.getDataSource(), command.getOldName()) + " " +
getNestedDeclaration(column.getTable(), command)));
}
@Override
protected void addObjectReorderActions(List<DBEPersistAction> actions, ObjectReorderCommand command) {
final MySQLTableColumn column = command.getObject();
String order = "FIRST";
if (column.getOrdinalPosition() > 0) {
for (MySQLTableColumn col : command.getObject().getTable().getCachedAttributes()) {
if (col.getOrdinalPosition() == column.getOrdinalPosition() - 1) {
order = "AFTER " + DBUtils.getQuotedIdentifier(col);
break;
}
}
}
actions.add(
new SQLDatabasePersistAction(
"Reorder column",
"ALTER TABLE " + column.getTable().getFullyQualifiedName(DBPEvaluationContext.DDL) + " CHANGE " +
DBUtils.getQuotedIdentifier(command.getObject()) + " " +
getNestedDeclaration(column.getTable(), command) + " " + order));
}
///////////////////////////////////////////////
// Reorder
@Override
public int getMinimumOrdinalPosition(MySQLTableColumn object) {
return 1;
}
@Override
public int getMaximumOrdinalPosition(MySQLTableColumn object) {
return object.getTable().getCachedAttributes().size();
}
@Override
public void setObjectOrdinalPosition(DBECommandContext commandContext, MySQLTableColumn object, List<MySQLTableColumn> siblingObjects, int newPosition) throws DBException {
processObjectReorder(commandContext, object, siblingObjects, newPosition);
}
}