001: /*
002: * EditTableConstraintsPanel.java
003: *
004: * Copyright (C) 2002, 2003, 2004, 2005, 2006 Takis Diakoumis
005: *
006: * This program is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU General Public License
008: * as published by the Free Software Foundation; either version 2
009: * of the License, or any later version.
010: *
011: * This program is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
014: * GNU General Public License for more details.
015: *
016: * You should have received a copy of the GNU General Public License
017: * along with this program; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
019: *
020: */
021:
022: package org.executequery.gui.table;
023:
024: import java.awt.Point;
025: import java.awt.event.FocusListener;
026: import java.awt.event.MouseAdapter;
027: import java.awt.event.MouseEvent;
028: import java.sql.SQLException;
029:
030: import java.util.Enumeration;
031: import java.util.Hashtable;
032: import java.util.Vector;
033:
034: import javax.swing.JOptionPane;
035: import javax.swing.JTable;
036:
037: import org.executequery.databasemediators.QuerySender;
038: import org.executequery.GUIUtilities;
039: import org.executequery.databasemediators.SqlStatementResult;
040: import org.executequery.gui.browser.ColumnConstraint;
041: import org.executequery.gui.browser.ColumnData;
042: import org.underworldlabs.swing.GUIUtils;
043: import org.underworldlabs.swing.table.ComboBoxCellEditor;
044: import org.underworldlabs.util.MiscUtils;
045:
046: /* ----------------------------------------------------------
047: * CVS NOTE: Changes to the CVS repository prior to the
048: * release of version 3.0.0beta1 has meant a
049: * resetting of CVS revision numbers.
050: * ----------------------------------------------------------
051: */
052:
053: /**
054: *
055: * @author Takis Diakoumis
056: * @version $Revision: 1.5 $
057: * @date $Date: 2006/06/09 01:44:37 $
058: */
059: public class EditTableConstraintsPanel extends TableConstraintsPanel {
060:
061: /** The table creator object - parent to this */
062: private TableConstraintFunction creator;
063:
064: /** The buffer off all SQL generated */
065: private StringBuffer sqlBuffer;
066:
067: /** The hosted schemas for the connection */
068: private Vector hostedSchemas;
069:
070: /** The original constraints */
071: private ColumnConstraint[] fKeys_orig;
072:
073: /** Holds temporary SQL text during modifications */
074: private Hashtable tempSqlText;
075:
076: public EditTableConstraintsPanel(TableConstraintFunction creator) {
077: super ();
078: this .creator = creator;
079: table.addMouseListener(new MouseHandler());
080:
081: sqlBuffer = new StringBuffer(100);
082: tempSqlText = new Hashtable();
083: }
084:
085: public ColumnData[] getTableColumnData() {
086: return creator.getTableColumnData();
087: }
088:
089: public int getMode() {
090: return EDIT_TABLE_MODE;
091: }
092:
093: public void updateCellEditor(int col, int row, String value) {
094: Vector fKeys = model.getKeys();
095: ColumnConstraint cc = (ColumnConstraint) fKeys.get(row);
096:
097: switch (col) {
098:
099: case 0:
100: case 1:
101: return;
102:
103: case 2:
104: setCellEditor(3, new ComboBoxCellEditor(
105: getTableColumnData()));
106: /*
107: if (value == ColumnConstraint.PRIMARY) {
108: setCellEditor(3, new ComboBoxCellEditor(getTableColumnData()));
109: }
110: else */
111: if (value == ColumnConstraint.FOREIGN) {
112:
113: if (hostedSchemas == null) {
114: hostedSchemas = creator.getHostedSchemasVector();
115: }
116: int schemaSize = hostedSchemas.size();
117:
118: // this means that cretor objects with null
119: // schema lists must generate the table values
120: // from elsewhere
121: if (schemaSize == 0) {
122: setCellEditor(5, new ComboBoxCellEditor(creator
123: .getSchemaTables(value)));
124: return;
125: }
126:
127: String[] schemas = new String[schemaSize];
128: for (int i = 0, k = hostedSchemas.size(); i < k; i++) {
129: schemas[i] = (String) hostedSchemas.elementAt(i);
130: }
131:
132: setCellEditor(4, new ComboBoxCellEditor(schemas));
133:
134: }
135:
136: break;
137:
138: case 3:
139: return;
140:
141: case 4:
142:
143: if (value == null || value.length() == 0) {
144: return;
145: }
146: setCellEditor(5, new ComboBoxCellEditor(creator
147: .getSchemaTables(value)));
148: break;
149:
150: case 5:
151: setCellEditor(6, new ComboBoxCellEditor(creator
152: .getColumnNamesVector(value, cc.getRefSchema())));
153:
154: case 6:
155: return;
156:
157: }
158:
159: }
160:
161: public void columnValuesChanged(int col, int row, String value) {
162: ColumnConstraint cc_orig = null;
163:
164: Vector fKeys = model.getKeys();
165: if (row < 0 || row > (fKeys.size() - 1)) {
166: return;
167: }
168:
169: ColumnConstraint cc = (ColumnConstraint) fKeys.elementAt(row);
170: sqlBuffer.setLength(0);
171:
172: if (row > fKeys_orig.length - 1 || cc.isNewConstraint()) {
173:
174: if (value == null) {
175: value = cc.getName();
176: } else if (value.length() == 0) {
177: tempSqlText.remove(ADD_CONSTRAINT + row);
178: generateSQL();
179: creator.setSQLText(sqlBuffer.toString(),
180: TableModifier.CONSTRAINT_VALUES);
181: return;
182: }
183:
184: sqlBuffer.append(ALTER_TABLE)
185: .append(creator.getTableName()).append(
186: ADD_CONSTRAINT).append(value).append(SPACE)
187: .append(
188: cc.getTypeName() == null ? EMPTY : cc
189: .getTypeName());
190:
191: switch (cc.getType()) {
192:
193: case ColumnConstraint.FOREIGN_KEY:
194: sqlBuffer.append(KEY).append(B_OPEN).append(
195: cc.getColumn()).append(B_CLOSE).append(SPACE)
196: .append(REFERENCES);
197:
198: if (cc.hasSchema()) {
199: sqlBuffer.append(cc.getRefSchema()).append(DOT);
200: }
201:
202: // sqlBuffer.append(creator.getTableName()).append(B_OPEN).
203: sqlBuffer.append(cc.getRefTable()).append(B_OPEN)
204: .append(cc.getRefColumn()).append(B_CLOSE)
205: .append(SEMI_COLON).append(NEW_LINE);
206: break;
207:
208: case ColumnConstraint.UNIQUE_KEY:
209: sqlBuffer.append(B_OPEN).append(cc.getColumn()).append(
210: B_CLOSE).append(SEMI_COLON).append(NEW_LINE);
211: break;
212:
213: case ColumnConstraint.PRIMARY_KEY:
214: sqlBuffer.append(KEY).append(B_OPEN).append(
215: cc.getColumn()).append(B_CLOSE).append(
216: SEMI_COLON).append(NEW_LINE);
217: break;
218:
219: default:
220: sqlBuffer.append(B_OPEN).append(cc.getColumn()).append(
221: B_CLOSE).append(SEMI_COLON).append(NEW_LINE);
222: break;
223:
224: }
225:
226: tempSqlText.put(ADD_CONSTRAINT + row, sqlBuffer.toString());
227:
228: } else {
229: cc_orig = fKeys_orig[row];
230:
231: if (cc_orig.getName().equals(value)) {
232: tempSqlText.remove(RENAME_CONSTRAINT + row);
233: }
234:
235: else {
236: sqlBuffer.append(ALTER_TABLE).append(
237: creator.getTableName()).append(
238: RENAME_CONSTRAINT).append(cc_orig.getName())
239: .append(TO).append(value).append(SEMI_COLON)
240: .append(NEW_LINE);
241: tempSqlText.put(RENAME_CONSTRAINT + row, sqlBuffer
242: .toString());
243: }
244:
245: }
246:
247: generateSQL();
248: creator.setSQLText(sqlBuffer.toString(),
249: TableModifier.CONSTRAINT_VALUES);
250:
251: }
252:
253: /**
254: * Returns the table displaying the constraint data.
255: *
256: * @return the table displaying the data
257: */
258: public JTable getTable() {
259: return table;
260: }
261:
262: public void addTableFocusListener(FocusListener listener) {
263: table.addFocusListener(listener);
264: }
265:
266: /**
267: * Clears all the SQL text.
268: */
269: public void reset() {
270: sqlBuffer.setLength(0);
271: tempSqlText.clear();
272: }
273:
274: /**
275: * Removes the SQL with the specified reference key
276: * from the temp buffer.
277: *
278: * @param key - the reference key to the SQL text
279: */
280: protected void removeFromBuffer(String key) {
281: tempSqlText.remove(key);
282: }
283:
284: /**
285: * Adds the specified value SQL text with the specified key
286: * to the temp SQL buffer.
287: *
288: * @param key - the key to reference the SQL text value
289: * @param value - the SQL text
290: */
291: protected void addToBuffer(String key, String value) {
292: tempSqlText.put(key, value);
293: }
294:
295: /**
296: * Generates the SQL statements based on the stored value changes.
297: */
298: protected void generateSQL() {
299: sqlBuffer.setLength(0);
300: for (Enumeration i = tempSqlText.elements(); i
301: .hasMoreElements();) {
302: sqlBuffer.append((String) i.nextElement());
303: }
304: }
305:
306: /**
307: * Stores the original unmodified key values.
308: */
309: public void setOriginalData() {
310: GUIUtils.startWorker(new Runnable() {
311: //SwingUtilities.invokeLater(new Runnable() {
312: public void run() {
313: Vector fKeys = model.getKeys();
314: int v_size = fKeys.size();
315:
316: fKeys_orig = new ColumnConstraint[v_size];
317: for (int i = 0; i < v_size; i++) {
318: fKeys_orig[i] = new ColumnConstraint();
319: fKeys_orig[i].setValues((ColumnConstraint) fKeys
320: .elementAt(i));
321: }
322: }
323: });
324: }
325:
326: /**
327: * Marks the currently selected column (table row)
328: * to be deleted/dropped from this table.
329: */
330: public void markDeleteRow() {
331: int row = getSelectedRow();
332: if (row == -1) {
333: return;
334: }
335:
336: table.editingStopped(null);
337: if (table.isEditing()) {
338: table.removeEditor();
339: }
340:
341: ColumnConstraint cc = getConstraintAt(row);
342: // if its already a new row - just remove it
343: if (cc.isNewConstraint()) {
344: //int newEditingRow = (row == tableVector.size() - 1) ? row - 1 : row;
345: //setEditingRow(newEditingRow);
346: model.deleteConstraint(row);
347: tempSqlText.remove(ADD_CONSTRAINT + row);
348:
349: // add the dummy row
350: if (model.getRowCount() == 0) {
351: model.insertRowAfter(true);
352: }
353:
354: // regenerate the SQL
355: generateSQL();
356: return;
357: }
358:
359: // create the drop statement
360: sqlBuffer.setLength(0);
361: sqlBuffer.append(ALTER_TABLE);
362:
363: /*
364: String schema = cc.getRefSchema();
365: if (!MiscUtilities.isNull(schema)) {
366: sqlBuffer.append(schema.toUpperCase()).append(DOT);
367: }
368: */
369:
370: sqlBuffer.append(cc.getTable());
371: sqlBuffer.append(DROP_CONSTRAINT);
372: sqlBuffer.append(cc.getName());
373: sqlBuffer.append(NEW_LINE);
374: tempSqlText.put(DROP_CONSTRAINT + row, sqlBuffer.toString());
375:
376: // mark the column to be dumped
377: cc.setMarkedDeleted(true);
378:
379: // regenerate the SQL
380: generateSQL();
381:
382: // fire the event
383: model.fireTableRowsUpdated(row, row);
384: }
385:
386: public void insertRowAfter() {
387: model.insertRowAfter(true);
388: }
389:
390: public void deleteSelectedRow(QuerySender qs) {
391: table.editingStopped(null);
392: if (table.isEditing()) {
393: table.removeEditor();
394: }
395:
396: int row = table.getSelectedRow();
397: ColumnConstraint cc = getConstraintAt(row);
398: if (!cc.isNewConstraint()) {
399: deleteSelectedRow(row, qs);
400: return;
401: }
402:
403: int newEditingRow = row == model.getRowCount() - 1 ? row - 1
404: : row;
405: table.setEditingRow(newEditingRow);
406:
407: model.deleteRow(row);
408: tempSqlText.remove(ADD_CONSTRAINT + row);
409: model.fireTableRowsDeleted(row, row);
410:
411: generateSQL();
412: creator.setSQLText(sqlBuffer.toString(),
413: TableModifier.CONSTRAINT_VALUES);
414:
415: if (model.getKeys().size() == 0) {
416: model.insertRowAfter(true);
417: }
418:
419: }
420:
421: public void deleteSelectedRow(int row, QuerySender qs) {
422: if (row == -1) {
423: return;
424: }
425:
426: ColumnConstraint cc = getConstraintAt(row);
427: int yesNo = GUIUtilities
428: .displayConfirmDialog("Are you sure you want to remove\nthe constraint "
429: + cc.getName() + "?");
430:
431: if (yesNo == JOptionPane.NO_OPTION)
432: return;
433:
434: else {
435:
436: try {
437:
438: SqlStatementResult result = qs
439: .updateRecords(ALTER_TABLE
440: + creator.getTableName()
441: + DROP_CONSTRAINT + cc.getName());
442: if (result.getUpdateCount() >= 0) {
443: int newEditingRow = (row == model.getRowCount() - 1 ? row - 1
444: : row);
445: table.setEditingRow(newEditingRow);
446:
447: model.deleteRow(row);
448: model.fireTableRowsDeleted(row, row);
449: } else {
450: SQLException e = result.getSqlException();
451: if (e != null) {
452: StringBuffer sb = new StringBuffer();
453: sb
454: .append(
455: "An error occurred applying the specified changes.")
456: .append("\n\nThe system returned:\n")
457: .append(MiscUtils.formatSQLError(e));
458: GUIUtilities.displayExceptionErrorDialog(sb
459: .toString(), e);
460: } else {
461: GUIUtilities.displayErrorMessage(result
462: .getErrorMessage());
463: }
464: }
465:
466: } catch (Exception e) {
467: e.printStackTrace();
468: StringBuffer sb = new StringBuffer();
469: sb
470: .append(
471: "An error occurred applying the specified changes.")
472: .append("\n\nThe system returned:\n").append(
473: e.getMessage());
474: GUIUtilities.displayExceptionErrorDialog(sb.toString(),
475: e);
476: }
477:
478: }
479: }
480:
481: public String getSQLText() {
482: return sqlBuffer.toString();
483: }
484:
485: public void columnValuesChanged() {
486: columnValuesChanged(-1, -1, null);
487: }
488:
489: private class MouseHandler extends MouseAdapter {
490: public MouseHandler() {
491: }
492:
493: public void mouseClicked(MouseEvent e) {
494: int mouseX = e.getX();
495: int mouseY = e.getY();
496:
497: int col = table.columnAtPoint(new Point(mouseX, mouseY));
498: // if we haven't clicked on column 0 - bail
499: if (col != 0) {
500: return;
501: }
502:
503: int row = table.rowAtPoint(new Point(mouseX, mouseY));
504: Object object = model.getValueAt(row, col);
505: if (object == null) {
506: return;
507: }
508:
509: ColumnConstraint cc = (ColumnConstraint) object;
510: // if this constraint is marked to be dropped, unmark it
511: if (cc.isMarkedDeleted()) {
512: cc.setMarkedDeleted(false);
513: tempSqlText.remove(DROP_CONSTRAINT + row);
514: model.fireTableRowsUpdated(row, row);
515: generateSQL();
516: creator.setSQLText();
517: }
518:
519: }
520: }
521:
522: }
|