001: package net.sourceforge.squirrel_sql.plugins.refactoring.commands;
002:
003: /*
004: * Copyright (C) 2006 Rob Manning
005: * manningr@users.sourceforge.net
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License
009: * as published by the Free Software Foundation; either version 2
010: * of the License, or any later version.
011: *
012: * This program is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
015: * GNU General Public License for more details.
016: *
017: * You should have received a copy of the GNU General Public License
018: * along with this program; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
020: */
021:
022: import java.awt.event.ActionEvent;
023: import java.awt.event.ActionListener;
024: import java.sql.SQLException;
025:
026: import net.sourceforge.squirrel_sql.client.session.ISession;
027: import net.sourceforge.squirrel_sql.client.session.SQLExecuterTask;
028: import net.sourceforge.squirrel_sql.fw.dialects.DialectFactory;
029: import net.sourceforge.squirrel_sql.fw.dialects.HibernateDialect;
030: import net.sourceforge.squirrel_sql.fw.dialects.UserCancelledOperationException;
031: import net.sourceforge.squirrel_sql.fw.gui.ErrorDialog;
032: import net.sourceforge.squirrel_sql.fw.sql.IDatabaseObjectInfo;
033: import net.sourceforge.squirrel_sql.fw.sql.ITableInfo;
034: import net.sourceforge.squirrel_sql.fw.sql.TableColumnInfo;
035: import net.sourceforge.squirrel_sql.fw.util.StringManager;
036: import net.sourceforge.squirrel_sql.fw.util.StringManagerFactory;
037: import net.sourceforge.squirrel_sql.fw.util.log.ILogger;
038: import net.sourceforge.squirrel_sql.fw.util.log.LoggerController;
039:
040: /**
041: * Implements showing a list of columns for a selected table to the
042: * user and dropping the ones that are selected when the user presses the
043: * drop column(s) button.
044: *
045: * @author rmmannin
046: *
047: */
048: public class RemoveColumnCommand extends AbstractRefactoringCommand {
049:
050: /** Logger for this class. */
051: private final static ILogger log = LoggerController
052: .createLogger(RemoveColumnCommand.class);
053:
054: /** Internationalized strings for this class. */
055: private static final StringManager s_stringMgr = StringManagerFactory
056: .getStringManager(RemoveColumnCommand.class);
057:
058: /**
059: * Ctor specifying the current session.
060: */
061: public RemoveColumnCommand(ISession session,
062: IDatabaseObjectInfo[] info) {
063: super (session, info);
064: }
065:
066: /**
067: * Execute this command.
068: */
069: public void execute() {
070: if (!(_info[0] instanceof ITableInfo)) {
071: return;
072: }
073: try {
074: ITableInfo ti = (ITableInfo) _info[0];
075: TableColumnInfo[] columns = _session.getSQLConnection()
076: .getSQLMetaData().getColumnInfo(ti);
077:
078: if (columns.length < 2) {
079: //i18n[RemoveColumnAction.singleObjectMessage=The table's only
080: //column cannot be removed - a table must have a least one column]
081: String msg = s_stringMgr
082: .getString("RemoveColumnAction.singleColumnMessage");
083: _session.showErrorMessage(msg);
084: return;
085: }
086:
087: try {
088: HibernateDialect dialect = DialectFactory.getDialect(
089: DialectFactory.DEST_TYPE, _session
090: .getApplication().getMainFrame(),
091: _session.getMetaData());
092: if (!dialect.supportsDropColumn()) {
093: //i18n[RemoveColumnAction.removeColumnNotSupported=This
094: //database ({0}) does not support dropping columns]
095: String msg = s_stringMgr
096: .getString(
097: "RemoveColumnAction.removeColumnNotSupported",
098: dialect.getDisplayName());
099: _session.showErrorMessage(msg);
100: return;
101: }
102: } catch (UserCancelledOperationException e) {
103: log.info("User cancelled add column request");
104: return;
105: }
106:
107: //Show the user a dialog with a list of columns and ask them to select
108: // one or more columns to drop
109: super .showColumnListDialog(new DropActionListener(),
110: new DropSQLActionListener(), 0);
111: } catch (SQLException e) {
112: log.error("Unexpected exception " + e.getMessage(), e);
113: }
114:
115: }
116:
117: protected void getSQLFromDialog(SQLResultListener listener) {
118: TableColumnInfo[] columns = columnListDialog
119: .getSelectedColumnList();
120:
121: HibernateDialect dialect = null;
122:
123: String[] result = new String[columns.length];
124: try {
125: dialect = DialectFactory.getDialect(
126: DialectFactory.DEST_TYPE, _session.getApplication()
127: .getMainFrame(), _session.getMetaData());
128: // TODO: add configuration for whether or not to qualify names.
129: String tableName = _info[0].getQualifiedName();
130: for (int i = 0; i < columns.length; i++) {
131: TableColumnInfo info = columns[i];
132: String columnName = info.getColumnName();
133: result[i] = dialect.getColumnDropSQL(tableName,
134: columnName);
135: }
136: } catch (UnsupportedOperationException e2) {
137: //i18n[RemoveColumnCommand.unsupportedOperationMsg=The {0} dialect
138: //doesn's support dropping columns]
139: String msg = s_stringMgr.getString(
140: "RemoveColumnCommand.unsupportedOperationMsg",
141: dialect.getDisplayName());
142:
143: _session.showMessage(msg);
144: } catch (UserCancelledOperationException e) {
145: // user cancelled selecting a dialog. do nothing?
146: }
147: listener.finished(result);
148: }
149:
150: private class DropSQLActionListener implements ActionListener,
151: SQLResultListener {
152: public void finished(String[] sqls) {
153: if (sqls == null || sqls.length == 0) {
154: // TODO: tell the user no changes
155: return;
156: }
157:
158: StringBuffer script = new StringBuffer();
159: for (int i = 0; i < sqls.length; i++) {
160: script.append(sqls[i]);
161: script.append(";\n\n");
162: }
163:
164: ErrorDialog sqldialog = new ErrorDialog(columnListDialog,
165: script.toString());
166: //i18n[RemoveColumnCommand.sqlDialogTitle=Remove Column SQL]
167: String title = s_stringMgr
168: .getString("RemoveColumnCommand.sqlDialogTitle");
169: sqldialog.setTitle(title);
170: sqldialog.setVisible(true);
171: }
172:
173: public void actionPerformed(ActionEvent e) {
174: getSQLFromDialog(this );
175: }
176: }
177:
178: private class DropActionListener implements ActionListener {
179:
180: public void actionPerformed(ActionEvent e) {
181: // TODO: should probably be using the ActionEvent and not directly
182: // referencing the columnListDialog.
183: if (columnListDialog == null) {
184: System.err.println("dialog was null");
185: return;
186: }
187: HibernateDialect dialect = null;
188: try {
189: dialect = DialectFactory.getDialect(
190: DialectFactory.DEST_TYPE, _session
191: .getApplication().getMainFrame(),
192: _session.getMetaData());
193: } catch (UserCancelledOperationException ex) {
194: log.info("User cancelled add column request");
195: return;
196: }
197:
198: CommandExecHandler handler = new CommandExecHandler(
199: _session);
200: // For each column that the user selected, issue the correct drop column
201: // statement. This may be db-specific
202: TableColumnInfo[] columns = columnListDialog
203: .getSelectedColumnList();
204: for (int i = 0; i < columns.length; i++) {
205: TableColumnInfo column = columns[i];
206: String dropSQL = dialect.getColumnDropSQL(column
207: .getTableName(), column.getColumnName());
208: log
209: .info("AddColumnCommand: executing SQL - "
210: + dropSQL);
211: SQLExecuterTask executer = new SQLExecuterTask(
212: _session, dropSQL, handler);
213:
214: // Execute the sql synchronously
215: executer.run();
216:
217: if (handler.exceptionEncountered()) {
218: // Stop processing statements
219: break;
220: }
221:
222: }
223: columnListDialog.setVisible(false);
224: }
225:
226: }
227:
228: }
|