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.awt.event.ItemEvent;
025: import java.awt.event.ItemListener;
026: import java.sql.SQLException;
027:
028: import javax.swing.JOptionPane;
029:
030: import net.sourceforge.squirrel_sql.client.gui.db.ColumnDetailDialog;
031: import net.sourceforge.squirrel_sql.client.gui.mainframe.MainFrame;
032: import net.sourceforge.squirrel_sql.client.session.ISession;
033: import net.sourceforge.squirrel_sql.client.session.SQLExecuterTask;
034: import net.sourceforge.squirrel_sql.fw.dialects.DialectFactory;
035: import net.sourceforge.squirrel_sql.fw.dialects.HibernateDialect;
036: import net.sourceforge.squirrel_sql.fw.dialects.UserCancelledOperationException;
037: import net.sourceforge.squirrel_sql.fw.gui.ErrorDialog;
038: import net.sourceforge.squirrel_sql.fw.sql.IDatabaseObjectInfo;
039: import net.sourceforge.squirrel_sql.fw.sql.ITableInfo;
040: import net.sourceforge.squirrel_sql.fw.sql.SQLDatabaseMetaData;
041: import net.sourceforge.squirrel_sql.fw.sql.TableColumnInfo;
042: import net.sourceforge.squirrel_sql.fw.util.StringManager;
043: import net.sourceforge.squirrel_sql.fw.util.StringManagerFactory;
044: import net.sourceforge.squirrel_sql.fw.util.log.ILogger;
045: import net.sourceforge.squirrel_sql.fw.util.log.LoggerController;
046: import net.sourceforge.squirrel_sql.plugins.refactoring.DBUtil;
047:
048: import org.hibernate.HibernateException;
049:
050: public class AddColumnCommand extends AbstractRefactoringCommand {
051:
052: /** Internationalized strings for this class. */
053: private static final StringManager s_stringMgr = StringManagerFactory
054: .getStringManager(AddColumnCommand.class);
055:
056: /** Logger for this class. */
057: private final static ILogger log = LoggerController
058: .createLogger(AddColumnCommand.class);
059:
060: private HibernateDialect dialect = null;
061:
062: private MainFrame mainFrame = null;
063:
064: /**
065: * Ctor specifying the current session.
066: */
067: public AddColumnCommand(ISession session, IDatabaseObjectInfo[] info) {
068: super (session, info);
069: }
070:
071: /**
072: * Execute this command. Save the session and selected objects in the plugin
073: * for use in paste command.
074: */
075: public void execute() {
076: String tableName = _info[0].getQualifiedName();
077: try {
078: dialect = DialectFactory.getDialect(
079: DialectFactory.DEST_TYPE, _session.getApplication()
080: .getMainFrame(), _session.getMetaData());
081: String dbName = dialect.getDisplayName();
082: columnDetailDialog = new ColumnDetailDialog(
083: ColumnDetailDialog.ADD_MODE);
084: columnDetailDialog.setTableName(tableName);
085: columnDetailDialog
086: .addExecuteListener(new AddButtonListener());
087: columnDetailDialog
088: .addEditSQLListener(new EditSQLListener());
089: columnDetailDialog
090: .addShowSQLListener(new ShowSQLButtonListener());
091: columnDetailDialog
092: .addDialectListListener(new DialectListListener());
093: mainFrame = _session.getApplication().getMainFrame();
094: columnDetailDialog.setLocationRelativeTo(mainFrame);
095: columnDetailDialog.setSelectedDialect(dbName);
096: columnDetailDialog.setVisible(true);
097: } catch (UserCancelledOperationException e) {
098: log.info("User cancelled add column request");
099: return;
100: }
101:
102: }
103:
104: protected void getSQLFromDialog(SQLResultListener listener) {
105: TableColumnInfo info = columnDetailDialog.getColumnInfo();
106: String[] result = null;
107: try {
108: result = DBUtil.getAlterSQLForColumnAddition(info, dialect);
109: } catch (HibernateException e1) {
110: String dataType = columnDetailDialog.getSelectedTypeName();
111: JOptionPane.showMessageDialog(columnDetailDialog, "The "
112: + dialect.getDisplayName()
113: + " dialect doesn't support the type " + dataType,
114: "Missing Dialect Type Mapping",
115: JOptionPane.ERROR_MESSAGE);
116: } catch (UnsupportedOperationException e2) {
117: String dbName = dialect.getDisplayName();
118: //i18n[AddColumnCommand.unsupportedOperationMsg=The {0} dialect
119: //doesn's support adding columns to tables]
120: String msg = s_stringMgr.getString(
121: "AddColumnCommand.unsupportedOperationMsg", dbName);
122: _session.showMessage(msg);
123:
124: }
125: listener.finished(result);
126: }
127:
128: private class AddButtonListener implements ActionListener,
129: SQLResultListener {
130:
131: public void actionPerformed(ActionEvent e) {
132: String columnName = columnDetailDialog.getColumnInfo()
133: .getColumnName();
134: String tableName = columnDetailDialog.getTableName();
135: if (!isColumnNameUnique(columnName)) {
136: JOptionPane.showMessageDialog(columnDetailDialog,
137: "Table " + tableName
138: + " already has a column called "
139: + columnName, "Problem",
140: JOptionPane.ERROR_MESSAGE);
141: return;
142: }
143: getSQLFromDialog(this );
144: }
145:
146: public void finished(String[] sqls) {
147:
148: if (sqls == null || sqls.length == 0) {
149: return;
150: }
151: CommandExecHandler handler = new CommandExecHandler(
152: _session);
153:
154: for (int i = 0; i < sqls.length; i++) {
155: String sql = sqls[i];
156:
157: log.info("AddColumnCommand: executing SQL - " + sql);
158:
159: SQLExecuterTask executer = new SQLExecuterTask(
160: _session, sql, handler);
161:
162: // Execute the sql synchronously
163: executer.run();
164:
165: if (handler.exceptionEncountered()) {
166: // Stop processing statements
167: break;
168: }
169: }
170: columnDetailDialog.setVisible(false);
171: }
172:
173: /**
174: * Tests to see if the specified column name already exists.
175: * @param columnName the column name to check.
176: * @return true if the column name doesn't exists; false otherwise
177: */
178: private boolean isColumnNameUnique(String columnName) {
179: boolean result = true;
180: SQLDatabaseMetaData d = _session.getSQLConnection()
181: .getSQLMetaData();
182: try {
183: TableColumnInfo[] columnInfos = d
184: .getColumnInfo((ITableInfo) _info[0]);
185: for (int i = 0; i < columnInfos.length; i++) {
186: TableColumnInfo columnInfo = columnInfos[i];
187: String existingColumnName = columnInfo
188: .getColumnName();
189: if (columnName.equalsIgnoreCase(existingColumnName)) {
190: result = false;
191: break;
192: }
193: }
194: } catch (SQLException e) {
195: log
196: .error("Unexpected exception - "
197: + e.getMessage(), e);
198: }
199: return result;
200: }
201: }
202:
203: private class ShowSQLButtonListener implements ActionListener,
204: SQLResultListener {
205:
206: public void finished(String[] sqls) {
207: if (sqls != null) {
208: StringBuffer script = new StringBuffer();
209: for (int i = 0; i < sqls.length; i++) {
210: script.append(sqls[i]);
211: script.append(";\n\n");
212: }
213:
214: ErrorDialog sqldialog = new ErrorDialog(
215: columnDetailDialog, script.toString());
216: //i18n[AddColumnCommand.sqlDialogTitle=Add column SQL]
217: String title = s_stringMgr
218: .getString("AddColumnCommand.sqlDialogTitle");
219: sqldialog.setTitle(title);
220: sqldialog.setVisible(true);
221: }
222: }
223:
224: public void actionPerformed(ActionEvent e) {
225: getSQLFromDialog(this );
226: }
227:
228: }
229:
230: private class DialectListListener implements ItemListener {
231:
232: public void itemStateChanged(ItemEvent e) {
233: String dbName = columnDetailDialog.getSelectedDBName();
234: dialect = DialectFactory.getDialect(dbName);
235: }
236: }
237: }
|