Source code: org/hsqldb/util/DatabaseManagerSwing.java
1 /* Copyrights and Licenses
2 *
3 * This product includes Hypersonic SQL.
4 * Originally developed by Thomas Mueller and the Hypersonic SQL Group.
5 *
6 * Copyright (c) 1995-2000 by the Hypersonic SQL Group. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without modification, are permitted
8 * provided that the following conditions are met:
9 * - Redistributions of source code must retain the above copyright notice, this list of conditions
10 * and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright notice, this list of
12 * conditions and the following disclaimer in the documentation and/or other materials
13 * provided with the distribution.
14 * - All advertising materials mentioning features or use of this software must display the
15 * following acknowledgment: "This product includes Hypersonic SQL."
16 * - Products derived from this software may not be called "Hypersonic SQL" nor may
17 * "Hypersonic SQL" appear in their names without prior written permission of the
18 * Hypersonic SQL Group.
19 * - Redistributions of any form whatsoever must retain the following acknowledgment: "This
20 * product includes Hypersonic SQL."
21 * This software is provided "as is" and any expressed or implied warranties, including, but
22 * not limited to, the implied warranties of merchantability and fitness for a particular purpose are
23 * disclaimed. In no event shall the Hypersonic SQL Group or its contributors be liable for any
24 * direct, indirect, incidental, special, exemplary, or consequential damages (including, but
25 * not limited to, procurement of substitute goods or services; loss of use, data, or profits;
26 * or business interruption). However caused any on any theory of liability, whether in contract,
27 * strict liability, or tort (including negligence or otherwise) arising in any way out of the use of this
28 * software, even if advised of the possibility of such damage.
29 * This software consists of voluntary contributions made by many individuals on behalf of the
30 * Hypersonic SQL Group.
31 *
32 *
33 * For work added by the HSQL Development Group:
34 *
35 * Copyright (c) 2001-2002, The HSQL Development Group
36 * All rights reserved.
37 *
38 * Redistribution and use in source and binary forms, with or without
39 * modification, are permitted provided that the following conditions are met:
40 *
41 * Redistributions of source code must retain the above copyright notice, this
42 * list of conditions and the following disclaimer, including earlier
43 * license statements (above) and comply with all above license conditions.
44 *
45 * Redistributions in binary form must reproduce the above copyright notice,
46 * this list of conditions and the following disclaimer in the documentation
47 * and/or other materials provided with the distribution, including earlier
48 * license statements (above) and comply with all above license conditions.
49 *
50 * Neither the name of the HSQL Development Group nor the names of its
51 * contributors may be used to endorse or promote products derived from this
52 * software without specific prior written permission.
53 *
54 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
55 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
56 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
57 * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
58 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
59 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
60 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
61 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
62 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
63 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
64 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
65 */
66
67
68 package org.hsqldb.util;
69
70 import java.awt.*;
71 import java.awt.event.*;
72 import java.awt.image.*;
73 import java.sql.*;
74 import java.io.File;
75 import java.util.*;
76 import javax.swing.*;
77 import javax.swing.tree.*;
78
79 // dmarshall@users - 20020101 - original swing port
80 // sqlbob@users 20020401 - patch 537501 by ulrivo - commandline arguments
81 // sqlbob@users 20020407 - patch 1.7.0 - reengineering and enhancements
82 // nickferguson@users 20021005 - patch 1.7.1 - enhancements
83
84 /**
85 * Swing Tool for manageing a JDBC database.<p>
86 * <pre>
87 * Usage: java DatabaseManagerSwing [-options]
88 * where options include:
89 * -driver <classname> jdbc driver class
90 * -url <name> jdbc url
91 * -user <name> username used for connection
92 * -password <password> password for this user
93 * -dir <path> default directory
94 * -script <file> reads from script file
95 *</pre>
96 * @version 1.7.0
97 */
98 public class DatabaseManagerSwing extends JApplet
99 implements ActionListener, WindowListener, KeyListener {
100
101 final static String NL = System.getProperty("line.separator");
102 static int iMaxRecent = 24;
103 Connection cConn;
104 DatabaseMetaData dMeta;
105 Statement sStatement;
106 JMenu mRecent;
107 String sRecent[];
108 int iRecent;
109 JTextArea txtCommand;
110 JScrollPane txtCommandScroll;
111 JButton butExecute;
112 JTree tTree;
113 JScrollPane tScrollPane;
114 DefaultTreeModel treeModel;
115 DefaultMutableTreeNode rootNode;
116 JPanel pResult;
117 long lTime;
118 int iResult; // 0: grid; 1: text
119 GridSwing gResult;
120 JTable gResultTable;
121 JScrollPane gScrollPane;
122 JTextArea txtResult;
123 JScrollPane txtResultScroll;
124 JSplitPane nsSplitPane; // Contains query over results
125 JSplitPane ewSplitPane; // Contains tree beside nsSplitPane
126 boolean bHelp;
127 JFrame fMain;
128 String ifHuge = "";
129 JToolBar jtoolbar;
130
131 // (ulrivo): variables set by arguments from the commandline
132 static String defDriver = "org.hsqldb.jdbcDriver";
133 static String defURL = "jdbc:hsqldb:.";
134 static String defUser = "sa";
135 static String defPassword = "";
136 static String defScript;
137 static String defDirectory;
138
139 public void init() {
140
141 DatabaseManagerSwing m = new DatabaseManagerSwing();
142
143 m.main();
144
145 try {
146 m.connect(ConnectionDialogSwing.createConnection(defDriver,
147 defURL, defUser, defPassword));
148 m.insertTestData();
149 m.refreshTree();
150 } catch (Exception e) {
151 e.printStackTrace();
152 }
153 }
154
155 public static void main(String arg[]) {
156
157 System.getProperties().put("sun.java2d.noddraw", "true");
158
159 // (ulrivo): read all arguments from the command line
160 String lowerArg;
161 boolean autoConnect = false;
162
163 for (int i = 0; i < arg.length; i++) {
164 lowerArg = arg[i].toLowerCase();
165
166 i++;
167
168 if (i == arg.length) {
169 showUsage();
170
171 return;
172 }
173
174 if (lowerArg.equals("-driver")) {
175 defDriver = arg[i];
176 autoConnect = true;
177 } else if (lowerArg.equals("-url")) {
178 defURL = arg[i];
179 autoConnect = true;
180 } else if (lowerArg.equals("-user")) {
181 defUser = arg[i];
182 autoConnect = true;
183 } else if (lowerArg.equals("-password")) {
184 defPassword = arg[i];
185 autoConnect = true;
186 } else if (lowerArg.equals("-dir")) {
187 defDirectory = arg[i];
188 } else if (lowerArg.equals("-script")) {
189 defScript = arg[i];
190 } else {
191 showUsage();
192
193 return;
194 }
195 }
196
197 DatabaseManagerSwing m = new DatabaseManagerSwing();
198
199 m.main();
200
201 Connection c = null;
202
203 try {
204 if (autoConnect) {
205 c = ConnectionDialogSwing.createConnection(defDriver, defURL,
206 defUser, defPassword);
207 } else {
208 c = ConnectionDialogSwing.createConnection(m.fMain,
209 "Connect");
210 }
211 } catch (Exception e) {
212 e.printStackTrace();
213 }
214
215 if (c == null) {
216 return;
217 }
218
219 m.connect(c);
220 }
221
222 private void connect(Connection c) {
223
224 if (c == null) {
225 return;
226 }
227
228 if (cConn != null) {
229 try {
230 cConn.close();
231 } catch (SQLException e) {}
232 }
233
234 cConn = c;
235
236 try {
237 dMeta = cConn.getMetaData();
238 sStatement = cConn.createStatement();
239
240 refreshTree();
241 } catch (SQLException e) {
242 e.printStackTrace();
243 }
244 }
245
246 private static void showUsage() {
247
248 System.out.println(
249 "Usage: java DatabaseManagerSwing [-options]\n"
250 + "where options include:\n"
251 + " -driver <classname> jdbc driver class\n"
252 + " -url <name> jdbc url\n"
253 + " -user <name> username used for connection\n"
254 + " -password <password> password for this user\n"
255 + " -dir <path> default directory\n"
256 + " -script <file> reads from script file\n");
257 }
258
259 private void insertTestData() {
260
261 try {
262 DatabaseManagerCommon.createTestTables(sStatement);
263 refreshTree();
264 txtCommand.setText(
265 DatabaseManagerCommon.createTestData(sStatement));
266 refreshTree();
267
268 for (int i = 0; i < DatabaseManagerCommon.testDataSql.length;
269 i++) {
270 addToRecent(DatabaseManagerCommon.testDataSql[i]);
271 }
272
273 execute();
274 } catch (SQLException e) {
275 e.printStackTrace();
276 }
277 }
278
279 void main() {
280
281 CommonSwing.setDefaultColor();
282
283 fMain = new JFrame("HSQL Database Manager");
284
285 // (ulrivo): An actual icon.
286 fMain.getContentPane().add(createToolBar(), "North");
287 fMain.setIconImage(CommonSwing.getIcon());
288 fMain.addWindowListener(this);
289
290 JMenuBar bar = new JMenuBar();
291
292 // used shortcuts: CERGTSIUDOLM
293 String fitems[] = {
294 "-Connect...", "--", "-Open Script...", "-Save Script...",
295 "-Save Result...", "--", "-Exit"
296 };
297
298 addMenu(bar, "File", fitems);
299
300 String vitems[] = {
301 "RRefresh Tree", "--", "GResults in Grid", "TResults in Text"
302 };
303
304 addMenu(bar, "View", vitems);
305
306 String sitems[] = {
307 "SSELECT", "IINSERT", "UUPDATE", "DDELETE", "---",
308 "-CREATE TABLE", "-DROP TABLE", "-CREATE INDEX", "-DROP INDEX",
309 "--", "-CHECKPOINT", "-SCRIPT", "-SET", "-SHUTDOWN", "--",
310 "-Test Script"
311 };
312
313 addMenu(bar, "Command", sitems);
314
315 mRecent = new JMenu("Recent");
316
317 bar.add(mRecent);
318
319 String soptions[] = {
320 "-AutoCommit on", "-AutoCommit off", "OCommit", "LRollback", "--",
321 "-Disable MaxRows", "-Set MaxRows to 100", "--", "-Logging on",
322 "-Logging off", "--", "-Insert test data"
323 };
324
325 addMenu(bar, "Options", soptions);
326
327 String stools[] = {
328 "-Dump", "-Restore", "-Transfer"
329 };
330
331 addMenu(bar, "Tools", stools);
332 fMain.setJMenuBar(bar);
333 initGUI();
334
335 sRecent = new String[iMaxRecent];
336
337 Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
338 Dimension size = fMain.getSize();
339
340 // (ulrivo): full size on screen with less than 640 width
341 if (d.width >= 640) {
342 fMain.setLocation((d.width - size.width) / 2,
343 (d.height - size.height) / 2);
344 } else {
345 fMain.setLocation(0, 0);
346 fMain.setSize(d);
347 }
348
349 fMain.show();
350
351 // (ulrivo): load query from command line
352 if (defScript != null) {
353 if (defDirectory != null) {
354 defScript = defDirectory + File.separator + defScript;
355 }
356
357 // if insert stmet is thousands of records...skip showing it
358 // as text. Too huge.
359 StringBuffer buf = new StringBuffer();
360
361 ifHuge = DatabaseManagerCommon.readFile(defScript);
362
363 if (4096 <= ifHuge.length()) {
364 buf.append(
365 "This huge file cannot be edited. Please execute\n");
366 txtCommand.setText(buf.toString());
367 } else {
368 txtCommand.setText(ifHuge);
369 }
370 }
371
372 txtCommand.requestFocus();
373 }
374
375 private void addMenu(JMenuBar b, String name, String items[]) {
376
377 JMenu menu = new JMenu(name);
378
379 addMenuItems(menu, items);
380 b.add(menu);
381 }
382
383 private void addMenuItems(JMenu f, String m[]) {
384
385 Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
386
387 for (int i = 0; i < m.length; i++) {
388 if (m[i].equals("--")) {
389 f.addSeparator();
390 } else if (m[i].equals("---")) {
391
392 // (ulrivo): full size on screen with less than 640 width
393 if (d.width >= 640) {
394 f.addSeparator();
395 } else {
396 return;
397 }
398 } else {
399 JMenuItem item = new JMenuItem(m[i].substring(1));
400 char c = m[i].charAt(0);
401
402 if (c != '-') {
403 item.setMnemonic(c);
404 }
405
406 item.addActionListener(this);
407 f.add(item);
408 }
409 }
410 }
411
412 public void keyPressed(KeyEvent k) {}
413
414 public void keyReleased(KeyEvent k) {}
415
416 public void keyTyped(KeyEvent k) {
417
418 if (k.getKeyChar() == '\n' && k.isControlDown()) {
419 k.consume();
420 execute();
421 }
422 }
423
424 public void actionPerformed(ActionEvent ev) {
425
426 String s = ev.getActionCommand();
427
428 if (s == null) {
429 if (ev.getSource() instanceof JMenuItem) {
430 JMenuItem i;
431
432 s = ((JMenuItem) ev.getSource()).getText();
433 }
434 }
435
436 /*
437 // button replace by toolbar
438 if (s.equals("Execute")) {
439 execute();
440 } else
441 */
442 if (s.equals("Exit")) {
443 windowClosing(null);
444 } else if (s.equals("Transfer")) {
445 Transfer.work(null);
446 } else if (s.equals("Dump")) {
447 Transfer.work(new String[]{ "-d" });
448 } else if (s.equals("Restore")) {
449 Transfer.work(new String[]{ "-r" });
450 } else if (s.equals("Logging on")) {
451 jdbcSystem.setLogToSystem(true);
452 } else if (s.equals("Logging off")) {
453 jdbcSystem.setLogToSystem(false);
454 } else if (s.equals("Refresh Tree")) {
455 refreshTree();
456 } else if (s.startsWith("#")) {
457 int i = Integer.parseInt(s.substring(1));
458
459 txtCommand.setText(sRecent[i]);
460 } else if (s.equals("Connect...")) {
461 connect(ConnectionDialogSwing.createConnection(fMain, "Connect"));
462 refreshTree();
463 } else if (s.equals("Results in Grid")) {
464 iResult = 0;
465
466 pResult.removeAll();
467 pResult.add(gScrollPane, BorderLayout.CENTER);
468 pResult.doLayout();
469 gResult.fireTableChanged(null);
470 pResult.repaint();
471 } else if (s.equals("Open Script...")) {
472 JFileChooser f = new JFileChooser(".");
473
474 f.setDialogTitle("Open Script...");
475
476 // (ulrivo): set default directory if set from command line
477 if (defDirectory != null) {
478 f.setCurrentDirectory(new File(defDirectory));
479 }
480
481 int option = f.showOpenDialog(fMain);
482
483 if (option == JFileChooser.APPROVE_OPTION) {
484 File file = f.getSelectedFile();
485
486 if (file != null) {
487 StringBuffer buf = new StringBuffer();
488
489 ifHuge = DatabaseManagerCommon.readFile(
490 file.getAbsolutePath());
491
492 if (4096 <= ifHuge.length()) {
493 buf.append(
494 "This huge file cannot be edited. Please execute\n");
495 txtCommand.setText(buf.toString());
496 } else {
497 txtCommand.setText(ifHuge);
498 }
499 }
500 }
501 } else if (s.equals("Save Script...")) {
502 JFileChooser f = new JFileChooser(".");
503
504 f.setDialogTitle("Save Script");
505
506 // (ulrivo): set default directory if set from command line
507 if (defDirectory != null) {
508 f.setCurrentDirectory(new File(defDirectory));
509 }
510
511 int option = f.showSaveDialog(fMain);
512
513 if (option == JFileChooser.APPROVE_OPTION) {
514 File file = f.getSelectedFile();
515
516 if (file != null) {
517 DatabaseManagerCommon.writeFile(file.getAbsolutePath(),
518 txtCommand.getText());
519 }
520 }
521 } else if (s.equals("Save Result...")) {
522 JFileChooser f = new JFileChooser(".");
523
524 f.setDialogTitle("Save Result...");
525
526 // (ulrivo): set default directory if set from command line
527 if (defDirectory != null) {
528 f.setCurrentDirectory(new File(defDirectory));
529 }
530
531 int option = f.showSaveDialog(fMain);
532
533 if (option == JFileChooser.APPROVE_OPTION) {
534 File file = f.getSelectedFile();
535
536 if (file != null) {
537 showResultInText();
538 DatabaseManagerCommon.writeFile(file.getAbsolutePath(),
539 txtResult.getText());
540 }
541 }
542 } else if (s.equals("Results in Text")) {
543 iResult = 1;
544
545 pResult.removeAll();
546 pResult.add(txtResultScroll, BorderLayout.CENTER);
547 pResult.doLayout();
548 showResultInText();
549 pResult.repaint();
550 } else if (s.equals("AutoCommit on")) {
551 try {
552 cConn.setAutoCommit(true);
553 } catch (SQLException e) {}
554 } else if (s.equals("AutoCommit off")) {
555 try {
556 cConn.setAutoCommit(false);
557 } catch (SQLException e) {}
558 } else if (s.equals("Commit")) {
559 try {
560 cConn.commit();
561 } catch (SQLException e) {}
562 } else if (s.equals("Insert test data")) {
563 insertTestData();
564 } else if (s.equals("Rollback")) {
565 try {
566 cConn.rollback();
567 } catch (SQLException e) {}
568 } else if (s.equals("Disable MaxRows")) {
569 try {
570 sStatement.setMaxRows(0);
571 } catch (SQLException e) {}
572 } else if (s.equals("Set MaxRows to 100")) {
573 try {
574 sStatement.setMaxRows(100);
575 } catch (SQLException e) {}
576 } else if (s.equals("SELECT")) {
577 showHelp(DatabaseManagerCommon.selectHelp);
578 } else if (s.equals("INSERT")) {
579 showHelp(DatabaseManagerCommon.insertHelp);
580 } else if (s.equals("UPDATE")) {
581 showHelp(DatabaseManagerCommon.updateHelp);
582 } else if (s.equals("DELETE")) {
583 showHelp(DatabaseManagerCommon.deleteHelp);
584 } else if (s.equals("CREATE TABLE")) {
585 showHelp(DatabaseManagerCommon.createTableHelp);
586 } else if (s.equals("DROP TABLE")) {
587 showHelp(DatabaseManagerCommon.dropTableHelp);
588 } else if (s.equals("CREATE INDEX")) {
589 showHelp(DatabaseManagerCommon.createIndexHelp);
590 } else if (s.equals("DROP INDEX")) {
591 showHelp(DatabaseManagerCommon.dropIndexHelp);
592 } else if (s.equals("CHECKPOINT")) {
593 showHelp(DatabaseManagerCommon.checkpointHelp);
594 } else if (s.equals("SCRIPT")) {
595 showHelp(DatabaseManagerCommon.scriptHelp);
596 } else if (s.equals("SHUTDOWN")) {
597 showHelp(DatabaseManagerCommon.shutdownHelp);
598 } else if (s.equals("SET")) {
599 showHelp(DatabaseManagerCommon.setHelp);
600 } else if (s.equals("Test Script")) {
601 showHelp(DatabaseManagerCommon.testHelp);
602 }
603 }
604
605 private void showHelp(String help[]) {
606
607 txtCommand.setText(help[0]);
608
609 bHelp = true;
610
611 pResult.removeAll();
612 pResult.add(txtResultScroll, BorderLayout.CENTER);
613 pResult.doLayout();
614 txtResult.setText(help[1]);
615 pResult.repaint();
616 txtCommand.requestFocus();
617 txtCommand.setCaretPosition(help[0].length());
618 }
619
620 public void windowActivated(WindowEvent e) {}
621
622 public void windowDeactivated(WindowEvent e) {}
623
624 public void windowClosed(WindowEvent e) {}
625
626 public void windowDeiconified(WindowEvent e) {}
627
628 public void windowIconified(WindowEvent e) {}
629
630 public void windowOpened(WindowEvent e) {}
631
632 public void windowClosing(WindowEvent ev) {
633
634 try {
635 cConn.close();
636 } catch (Exception e) {}
637
638 fMain.dispose();
639 System.exit(0);
640 }
641
642 private void clear() {
643
644 ifHuge = "";
645
646 txtCommand.setText(ifHuge);
647 }
648
649 private void execute() {
650
651 gResult.clear();
652
653 String sCmd = null;
654
655 if (4096 <= ifHuge.length()) {
656 sCmd = ifHuge;
657 } else {
658 sCmd = txtCommand.getText();
659 }
660
661 if (sCmd.startsWith("-->>>TEST<<<--")) {
662 testPerformance();
663
664 return;
665 }
666
667 String g[] = new String[1];
668
669 try {
670 lTime = System.currentTimeMillis();
671
672 sStatement.execute(sCmd);
673
674 int r = sStatement.getUpdateCount();
675
676 if (r == -1) {
677 formatResultSet(sStatement.getResultSet());
678 } else {
679 g[0] = "update count";
680
681 gResult.setHead(g);
682
683 g[0] = "" + r;
684
685 gResult.addRow(g);
686 }
687
688 lTime = System.currentTimeMillis() - lTime;
689
690 addToRecent(txtCommand.getText());
691 gResult.fireTableChanged(null);
692 } catch (SQLException e) {
693 lTime = System.currentTimeMillis() - lTime;
694 g[0] = "SQL Error";
695
696 gResult.setHead(g);
697
698 String s = e.getMessage();
699
700 s += " / Error Code: " + e.getErrorCode();
701 s += " / State: " + e.getSQLState();
702 g[0] = s;
703
704 gResult.addRow(g);
705 gResult.fireTableChanged(null);
706 }
707
708 updateResult();
709 System.gc();
710 }
711
712 private void updateResult() {
713
714 if (iResult == 0) {
715
716 // in case 'help' has removed the grid
717 if (bHelp) {
718 pResult.removeAll();
719 pResult.add(gScrollPane, BorderLayout.CENTER);
720 pResult.doLayout();
721 gResult.fireTableChanged(null);
722 pResult.repaint();
723
724 bHelp = false;
725 }
726 } else {
727 showResultInText();
728 }
729
730 txtCommand.selectAll();
731 txtCommand.requestFocus();
732 }
733
734 private void formatResultSet(ResultSet r) {
735
736 if (r == null) {
737 String g[] = new String[1];
738
739 g[0] = "Result";
740
741 gResult.setHead(g);
742
743 g[0] = "(empty)";
744
745 gResult.addRow(g);
746
747 return;
748 }
749
750 try {
751 ResultSetMetaData m = r.getMetaData();
752 int col = m.getColumnCount();
753 String h[] = new String[col];
754
755 for (int i = 1; i <= col; i++) {
756 h[i - 1] = m.getColumnLabel(i);
757 }
758
759 gResult.setHead(h);
760
761 while (r.next()) {
762 for (int i = 1; i <= col; i++) {
763 h[i - 1] = r.getString(i);
764
765 if (r.wasNull()) {
766 h[i - 1] = "(null)";
767 }
768 }
769
770 gResult.addRow(h);
771 }
772
773 r.close();
774 } catch (SQLException e) {}
775 }
776
777 private void testPerformance() {
778
779 String all = txtCommand.getText();
780 StringBuffer b = new StringBuffer();
781 long total = 0;
782
783 for (int i = 0; i < all.length(); i++) {
784 char c = all.charAt(i);
785
786 if (c != '\n') {
787 b.append(c);
788 }
789 }
790
791 all = b.toString();
792
793 String g[] = new String[4];
794
795 g[0] = "ms";
796 g[1] = "count";
797 g[2] = "sql";
798 g[3] = "error";
799
800 gResult.setHead(g);
801
802 int max = 1;
803
804 lTime = System.currentTimeMillis() - lTime;
805
806 while (!all.equals("")) {
807 int i = all.indexOf(';');
808 String sql;
809
810 if (i != -1) {
811 sql = all.substring(0, i);
812 all = all.substring(i + 1);
813 } else {
814 sql = all;
815 all = "";
816 }
817
818 if (sql.startsWith("--#")) {
819 max = Integer.parseInt(sql.substring(3));
820
821 continue;
822 } else if (sql.startsWith("--")) {
823 continue;
824 }
825
826 g[2] = sql;
827
828 long l = 0;
829
830 try {
831 l = DatabaseManagerCommon.testStatement(sStatement, sql, max);
832 total += l;
833 g[0] = "" + l;
834 g[1] = "" + max;
835 g[3] = "";
836 } catch (SQLException e) {
837 g[0] = g[1] = "n/a";
838 g[3] = e.toString();
839 }
840
841 gResult.addRow(g);
842 System.out.println(l + " ms : " + sql);
843 }
844
845 g[0] = "" + total;
846 g[1] = "total";
847 g[2] = "";
848
849 gResult.addRow(g);
850
851 lTime = System.currentTimeMillis() - lTime;
852
853 updateResult();
854 }
855
856 /**
857 * Method declaration
858 *
859 */
860 private void showResultInText() {
861
862 String col[] = gResult.getHead();
863 int width = col.length;
864 int size[] = new int[width];
865 Vector data = gResult.getData();
866 String row[];
867 int height = data.size();
868
869 for (int i = 0; i < width; i++) {
870 size[i] = col[i].length();
871 }
872
873 for (int i = 0; i < height; i++) {
874 row = (String[]) data.elementAt(i);
875
876 for (int j = 0; j < width; j++) {
877 int l = row[j].length();
878
879 if (l > size[j]) {
880 size[j] = l;
881 }
882 }
883 }
884
885 StringBuffer b = new StringBuffer();
886
887 for (int i = 0; i < width; i++) {
888 b.append(col[i]);
889
890 for (int l = col[i].length(); l <= size[i]; l++) {
891 b.append(' ');
892 }
893 }
894
895 b.append(NL);
896
897 for (int i = 0; i < width; i++) {
898 for (int l = 0; l < size[i]; l++) {
899 b.append('-');
900 }
901
902 b.append(' ');
903 }
904
905 b.append(NL);
906
907 for (int i = 0; i < height; i++) {
908 row = (String[]) data.elementAt(i);
909
910 for (int j = 0; j < width; j++) {
911 b.append(row[j]);
912
913 for (int l = row[j].length(); l <= size[j]; l++) {
914 b.append(' ');
915 }
916 }
917
918 b.append(NL);
919 }
920
921 b.append(NL + height + " row(s) in " + lTime + " ms");
922 txtResult.setText(b.toString());
923 }
924
925 private void addToRecent(String s) {
926
927 for (int i = 0; i < iMaxRecent; i++) {
928 if (s.equals(sRecent[i])) {
929 return;
930 }
931 }
932
933 if (sRecent[iRecent] != null) {
934 mRecent.remove(iRecent);
935 }
936
937 sRecent[iRecent] = s;
938
939 if (s.length() > 43) {
940 s = s.substring(0, 40) + "...";
941 }
942
943 JMenuItem item = new JMenuItem(s);
944
945 item.setActionCommand("#" + iRecent);
946 item.addActionListener(this);
947 mRecent.insert(item, iRecent);
948
949 iRecent = (iRecent + 1) % iMaxRecent;
950 }
951
952 private void initGUI() {
953
954 JPanel pCommand = new JPanel();
955
956 pResult = new JPanel();
957 nsSplitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, pCommand,
958 pResult);
959
960 pCommand.setLayout(new BorderLayout());
961 pResult.setLayout(new BorderLayout());
962
963 Font fFont = new Font("Dialog", Font.PLAIN, 12);
964
965 txtCommand = new JTextArea(5, 40);
966
967 txtCommand.setMargin(new Insets(5, 5, 5, 5));
968 txtCommand.addKeyListener(this);
969
970 txtCommandScroll = new JScrollPane(txtCommand);
971 txtResult = new JTextArea(20, 40);
972
973 txtResult.setMargin(new Insets(5, 5, 5, 5));
974
975 txtResultScroll = new JScrollPane(txtResult);
976
977 txtCommand.setFont(fFont);
978 txtResult.setFont(new Font("Courier", Font.PLAIN, 12));
979 /*
980 // button replaced by toolbar
981 butExecute = new JButton("Execute");
982
983 butExecute.addActionListener(this);
984 pCommand.add(butExecute, BorderLayout.EAST);
985 */
986 pCommand.add(txtCommandScroll, BorderLayout.CENTER);
987
988 gResult = new GridSwing();
989 gResultTable = new JTable(gResult);
990 gScrollPane = new JScrollPane(gResultTable);
991
992 //getContentPane().setLayout(new BorderLayout());
993 pResult.add(gScrollPane, BorderLayout.CENTER);
994
995 // Set up the tree
996 rootNode = new DefaultMutableTreeNode("Connection");
997 treeModel = new DefaultTreeModel(rootNode);
998 tTree = new JTree(treeModel);
999 tScrollPane = new JScrollPane(tTree);
1000
1001 tScrollPane.setPreferredSize(new Dimension(120, 400));
1002 tScrollPane.setMinimumSize(new Dimension(70, 100));
1003 txtCommandScroll.setPreferredSize(new Dimension(360, 100));
1004 txtCommandScroll.setMinimumSize(new Dimension(180, 100));
1005 gScrollPane.setPreferredSize(new Dimension(460, 300));
1006
1007 ewSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
1008 tScrollPane, nsSplitPane);
1009
1010 fMain.getContentPane().add(ewSplitPane, BorderLayout.CENTER);
1011 doLayout();
1012 fMain.pack();
1013 }
1014
1015 /* Simple tree node factory method - set's parent and user object.
1016 */
1017 private DefaultMutableTreeNode makeNode(Object userObject,
1018 MutableTreeNode parent) {
1019
1020 DefaultMutableTreeNode node = new DefaultMutableTreeNode(userObject);
1021
1022 if (parent != null) {
1023 treeModel.insertNodeInto(node, parent, parent.getChildCount());
1024 }
1025
1026 return node;
1027 }
1028
1029 /* Clear all existing nodes from the tree model and rebuild from scratch.
1030 */
1031 protected void refreshTree() {
1032
1033 DefaultMutableTreeNode propertiesNode;
1034 DefaultMutableTreeNode leaf;
1035
1036 // First clear the existing tree by simply enumerating
1037 // over the root node's children and removing them one by one.
1038 while (treeModel.getChildCount(rootNode) > 0) {
1039 DefaultMutableTreeNode child =
1040 (DefaultMutableTreeNode) treeModel.getChild(rootNode, 0);
1041
1042 treeModel.removeNodeFromParent(child);
1043 child.removeAllChildren();
1044 child.removeFromParent();
1045 }
1046
1047 treeModel.nodeStructureChanged(rootNode);
1048 treeModel.reload();
1049 tScrollPane.repaint();
1050
1051 // Now rebuild the tree below its root
1052 try {
1053
1054 // Start by naming the root node from its URL:
1055 rootNode.setUserObject(dMeta.getURL());
1056
1057 // get metadata about user tables by building a vector of table names
1058 String usertables[] = {
1059 "TABLE", "GLOBAL TEMPORARY", "VIEW"
1060 };
1061 ResultSet result = dMeta.getTables(null, null, null, usertables);
1062 Vector tables = new Vector();
1063
1064 // sqlbob@users Added remarks.
1065 Vector remarks = new Vector();
1066
1067 while (result.next()) {
1068 tables.addElement(result.getString(3));
1069 remarks.addElement(result.getString(5));
1070 }
1071
1072 result.close();
1073
1074 // For each table, build a tree node with interesting info
1075 for (int i = 0; i < tables.size(); i++) {
1076 String name = (String) tables.elementAt(i);
1077 DefaultMutableTreeNode tableNode = makeNode(name, rootNode);
1078 ResultSet col = dMeta.getColumns(null, null, name, null);
1079
1080 // sqlbob@users Added remarks.
1081 String remark = (String) remarks.elementAt(i);
1082
1083 if ((remark != null) &&!remark.trim().equals("")) {
1084 makeNode(remark, tableNode);
1085 }
1086
1087 // With a child for each column containing pertinent attributes
1088 while (col.next()) {
1089 String c = col.getString(4);
1090 DefaultMutableTreeNode columnNode = makeNode(c,
1091 tableNode);
1092 String type = col.getString(6);
1093
1094 makeNode("Type: " + type, columnNode);
1095
1096 boolean nullable = col.getInt(11)
1097 != DatabaseMetaData.columnNoNulls;
1098
1099 makeNode("Nullable: " + nullable, columnNode);
1100 }
1101
1102 col.close();
1103
1104 DefaultMutableTreeNode indexesNode = makeNode("Indices",
1105 tableNode);
1106 ResultSet ind = dMeta.getIndexInfo(null, null, name, false,
1107 false);
1108 String oldiname = null;
1109
1110 // A child node to contain each index - and its attributes
1111 while (ind.next()) {
1112 DefaultMutableTreeNode indexNode = null;
1113 boolean nonunique = ind.getBoolean(4);
1114 String iname = ind.getString(6);
1115
1116 if ((oldiname == null ||!oldiname.equals(iname))) {
1117 indexNode = makeNode(iname, indexesNode);
1118
1119 makeNode("Unique: " + !nonunique, indexNode);
1120
1121 oldiname = iname;
1122 }
1123
1124 // And the ordered column list for index components
1125 makeNode(ind.getString(9), indexNode);
1126 }
1127
1128 ind.close();
1129 }
1130
1131 // Finally - a little additional metadata on this connection
1132 propertiesNode = makeNode("Properties", rootNode);
1133
1134 makeNode("User: " + dMeta.getUserName(), propertiesNode);
1135 makeNode("ReadOnly: " + cConn.isReadOnly(), propertiesNode);
1136 makeNode("AutoCommit: " + cConn.getAutoCommit(), propertiesNode);
1137 makeNode("Driver: " + dMeta.getDriverName(), propertiesNode);
1138 makeNode("Product: " + dMeta.getDatabaseProductName(),
1139 propertiesNode);
1140 makeNode("Version: " + dMeta.getDatabaseProductVersion(),
1141 propertiesNode);
1142 } catch (SQLException se) {
1143 propertiesNode = makeNode("Error getting metadata:", rootNode);
1144
1145 makeNode(se.getMessage(), propertiesNode);
1146 makeNode(se.getSQLState(), propertiesNode);
1147 }
1148
1149 treeModel.nodeStructureChanged(rootNode);
1150 treeModel.reload();
1151 tScrollPane.repaint();
1152 }
1153
1154 protected JToolBar createToolBar() {
1155
1156 JToolBar jtoolbar = new JToolBar();
1157
1158 jtoolbar.putClientProperty("JToolBar.isRollover", Boolean.TRUE);
1159
1160 //---------------------------------------
1161 JButton jbuttonClear = new JButton("Clear SQL Statement");
1162
1163 jbuttonClear.setToolTipText("Clear SQL Statement");
1164 jbuttonClear.addActionListener(new ActionListener() {
1165
1166 public void actionPerformed(ActionEvent actionevent) {
1167 clear();
1168 }
1169 });
1170
1171 //---------------------------------------
1172 JButton jbuttonExecute = new JButton("Execute SQL Statement");
1173
1174 jbuttonExecute.setToolTipText("Execute SQL Statement");
1175 jbuttonExecute.addActionListener(new ActionListener() {
1176
1177 public void actionPerformed(ActionEvent actionevent) {
1178 execute();
1179 }
1180 });
1181 jtoolbar.addSeparator();
1182 jtoolbar.add(jbuttonClear);
1183 jtoolbar.addSeparator();
1184 jtoolbar.add(jbuttonExecute);
1185 jtoolbar.addSeparator();
1186 jbuttonClear.setAlignmentY(0.5F);
1187 jbuttonClear.setAlignmentX(0.5F);
1188 jbuttonExecute.setAlignmentY(0.5F);
1189 jbuttonExecute.setAlignmentX(0.5F);
1190
1191 return jtoolbar;
1192 }
1193}