0001: /* Copyright (c) 2001-2005, The HSQL Development Group
0002: * All rights reserved.
0003: *
0004: * Redistribution and use in source and binary forms, with or without
0005: * modification, are permitted provided that the following conditions are met:
0006: *
0007: * Redistributions of source code must retain the above copyright notice, this
0008: * list of conditions and the following disclaimer.
0009: *
0010: * Redistributions in binary form must reproduce the above copyright notice,
0011: * this list of conditions and the following disclaimer in the documentation
0012: * and/or other materials provided with the distribution.
0013: *
0014: * Neither the name of the HSQL Development Group nor the names of its
0015: * contributors may be used to endorse or promote products derived from this
0016: * software without specific prior written permission.
0017: *
0018: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0019: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0020: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0021: * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
0022: * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
0023: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
0024: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
0025: * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
0026: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0027: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
0028: * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0029: */
0030:
0031: package org.hsqldb.util;
0032:
0033: import java.applet.Applet;
0034: import java.io.File;
0035: import java.io.IOException;
0036: import java.sql.Connection;
0037: import java.sql.DatabaseMetaData;
0038: import java.sql.ResultSet;
0039: import java.sql.ResultSetMetaData;
0040: import java.sql.SQLException;
0041: import java.sql.Statement;
0042: import java.util.Vector;
0043: import java.awt.BorderLayout;
0044: import java.awt.Button;
0045: import java.awt.Color;
0046: import java.awt.Dimension;
0047: import java.awt.FileDialog;
0048: import java.awt.Font;
0049: import java.awt.Frame;
0050: import java.awt.Image;
0051: import java.awt.Menu;
0052: import java.awt.MenuBar;
0053: import java.awt.MenuItem;
0054: import java.awt.MenuShortcut;
0055: import java.awt.Panel;
0056: import java.awt.TextArea;
0057: import java.awt.Toolkit;
0058: import java.awt.event.ActionEvent;
0059: import java.awt.event.ActionListener;
0060: import java.awt.event.KeyEvent;
0061: import java.awt.event.KeyListener;
0062: import java.awt.event.WindowEvent;
0063: import java.awt.event.WindowListener;
0064: import java.awt.image.MemoryImageSource;
0065:
0066: import org.hsqldb.lib.java.JavaSystem;
0067:
0068: // sqlbob@users 20020401 - patch 1.7.0 by sqlbob (RMP) - enhancements
0069: // sqlbob@users 20020401 - patch 537501 by ulrivo - command line arguments
0070: // sqlbob@users 20020407 - patch 1.7.0 - reengineering
0071: // nickferguson@users 20021005 - patch 1.7.1 - enhancements
0072:
0073: /**
0074: * AWT Tool for manageing a JDBC database.<p>
0075: * <pre>
0076: * Usage: java DatabaseManagerSwing [--options]
0077: * where options include:
0078: * --driver <classname> jdbc driver class
0079: * --url <name> jdbc url
0080: * --user <name> username used for connection
0081: * --password <password> password for this user
0082: * --urlid <urlid> get connection info from RC file
0083: * --rcfile <file> use instead of default (with urlid)
0084: * --dir <path> default directory
0085: * --script <file> reads from script file
0086: *</pre>
0087: * Tue Apr 26 16:38:54 EDT 2005
0088: * Switched default switch method from "-switch" to "--switch" because
0089: * "-switch" usage is ambiguous as used here. Single switches should
0090: * be reserved for single-letter switches which can be mixed like
0091: * "-u -r -l" = "-url". -blaine
0092: *
0093: * @author Thomas Mueller (Hypersonic SQL Group)
0094: * @version 1.8.0
0095: * @since Hypersonic SQL
0096: */
0097: public class DatabaseManager extends Applet implements ActionListener,
0098: WindowListener, KeyListener {
0099:
0100: private static final String DEFAULT_RCFILE = System
0101: .getProperty("user.home")
0102: + "/dbmanager.rc";
0103: static final String NL = System.getProperty("line.separator");
0104: static final int iMaxRecent = 24;
0105: private static boolean TT_AVAILABLE = false;
0106:
0107: static {
0108: try {
0109: Class.forName(DatabaseManagerSwing.class.getPackage()
0110: .getName()
0111: + ".Transfer");
0112:
0113: TT_AVAILABLE = true;
0114: } catch (Throwable t) {
0115: }
0116: }
0117:
0118: private static final String HELP_TEXT = "See the forums, mailing lists, and HSQLDB User Guide\n"
0119: + "at http://hsqldb.org.\n\n"
0120: + "Please paste the following version identifier with any\n"
0121: + "problem reports or help requests: $Revision: 1.33 $"
0122: + (TT_AVAILABLE ? ""
0123: : ("\n\nTransferTool classes are not in CLASSPATH.\n"
0124: + "To enable the Tools menu, add 'transfer.jar' to your class path."));;
0125: private static final String ABOUT_TEXT = "$Revision: 1.33 $ of DatabaseManagerSwing\n\n"
0126: + "Copyright (c) 1995-2000, The Hypersonic SQL Group.\n"
0127: + "Copyright (c) 2001-2005, The HSQL Development Group.\n"
0128: + "http://hsqldb.org (User Guide available at this site).\n\n\n"
0129: + "You may use and redistribute according to the HSQLDB\n"
0130: + "license documented in the source code and at the web\n"
0131: + "site above."
0132: + (TT_AVAILABLE ? "\n\nTransferTool options are available."
0133: : "");
0134: Connection cConn;
0135: DatabaseMetaData dMeta;
0136: Statement sStatement;
0137: Menu mRecent;
0138: String[] sRecent;
0139: int iRecent;
0140: TextArea txtCommand;
0141: Button butExecute;
0142: Button butClear;
0143: Tree tTree;
0144: Panel pResult;
0145: long lTime;
0146: int iResult; // 0: grid; 1: text
0147: Grid gResult;
0148: TextArea txtResult;
0149: boolean bHelp;
0150: Frame fMain;
0151: Image imgEmpty;
0152: static boolean bMustExit;
0153: String ifHuge = "";
0154:
0155: // (ulrivo): variables set by arguments from the commandline
0156: static String defDriver = "org.hsqldb.jdbcDriver";
0157: static String defURL = "jdbc:hsqldb:.";
0158: static String defUser = "sa";
0159: static String defPassword = "";
0160: static String defScript;
0161: static String defDirectory;
0162:
0163: /**
0164: * Method declaration
0165: *
0166: *
0167: * @param c
0168: */
0169: public void connect(Connection c) {
0170:
0171: if (c == null) {
0172: return;
0173: }
0174:
0175: if (cConn != null) {
0176: try {
0177: cConn.close();
0178: } catch (SQLException e) {
0179: }
0180: }
0181:
0182: cConn = c;
0183:
0184: try {
0185: dMeta = cConn.getMetaData();
0186: sStatement = cConn.createStatement();
0187:
0188: refreshTree();
0189: } catch (SQLException e) {
0190: e.printStackTrace();
0191: }
0192: }
0193:
0194: /**
0195: * Method declaration
0196: *
0197: */
0198: public void init() {
0199:
0200: DatabaseManager m = new DatabaseManager();
0201:
0202: m.main();
0203:
0204: try {
0205: m.connect(ConnectionDialog.createConnection(defDriver,
0206: defURL, defUser, defPassword));
0207: m.insertTestData();
0208: m.refreshTree();
0209: } catch (Exception e) {
0210: e.printStackTrace();
0211: }
0212: }
0213:
0214: /**
0215: * Method declaration
0216: *
0217: *
0218: * @param arg
0219: */
0220: public static void main(String[] arg) {
0221:
0222: System.getProperties().put("sun.java2d.noddraw", "true");
0223:
0224: // (ulrivo): read all arguments from the command line
0225: String lowerArg;
0226: String urlid = null;
0227: String rcFile = null;
0228: boolean autoConnect = false;
0229: boolean urlidConnect = false;
0230:
0231: bMustExit = true;
0232:
0233: for (int i = 0; i < arg.length; i++) {
0234: lowerArg = arg[i].toLowerCase();
0235:
0236: if (lowerArg.length() > 1 && lowerArg.charAt(1) == '-') {
0237: lowerArg = lowerArg.substring(1);
0238: }
0239:
0240: i++;
0241:
0242: if (i == arg.length) {
0243: showUsage();
0244:
0245: return;
0246: }
0247:
0248: if (lowerArg.equals("-driver")) {
0249: defDriver = arg[i];
0250: autoConnect = true;
0251: } else if (lowerArg.equals("-url")) {
0252: defURL = arg[i];
0253: autoConnect = true;
0254: } else if (lowerArg.equals("-user")) {
0255: defUser = arg[i];
0256: autoConnect = true;
0257: } else if (lowerArg.equals("-password")) {
0258: defPassword = arg[i];
0259: autoConnect = true;
0260: } else if (lowerArg.equals("-urlid")) {
0261: urlid = arg[i];
0262: urlidConnect = true;
0263: } else if (lowerArg.equals("-rcfile")) {
0264: rcFile = arg[i];
0265: urlidConnect = true;
0266: } else if (lowerArg.equals("-dir")) {
0267: defDirectory = arg[i];
0268: } else if (lowerArg.equals("-script")) {
0269: defScript = arg[i];
0270: } else if (lowerArg.equals("-noexit")) {
0271: bMustExit = false;
0272:
0273: i--;
0274: } else {
0275: showUsage();
0276:
0277: return;
0278: }
0279: }
0280:
0281: DatabaseManager m = new DatabaseManager();
0282:
0283: m.main();
0284:
0285: Connection c = null;
0286:
0287: try {
0288: if (autoConnect && urlidConnect) {
0289: throw new IllegalArgumentException(
0290: "You may not specify both (urlid) AND (url/user/password).");
0291: }
0292:
0293: if (autoConnect) {
0294: c = ConnectionDialog.createConnection(defDriver,
0295: defURL, defUser, defPassword);
0296: } else if (urlidConnect) {
0297: if (urlid == null) {
0298: throw new IllegalArgumentException(
0299: "You must specify an 'urlid' to use an RC file");
0300: }
0301:
0302: autoConnect = true;
0303: c = (new RCData(new File(
0304: (rcFile == null) ? DEFAULT_RCFILE : rcFile),
0305: urlid).getConnection(null, System
0306: .getProperty("sqlfile.charset"), System
0307: .getProperty("javax.net.ssl.trustStore")));
0308: } else {
0309: c = ConnectionDialog.createConnection(m.fMain,
0310: "Connect");
0311: }
0312: } catch (Exception e) {
0313: e.printStackTrace();
0314: }
0315:
0316: if (c == null) {
0317: return;
0318: }
0319:
0320: m.connect(c);
0321: }
0322:
0323: private static void showUsage() {
0324:
0325: System.out
0326: .println("Usage: java DatabaseManager [--options]\n"
0327: + "where options include:\n"
0328: + " --driver <classname> jdbc driver class\n"
0329: + " --url <name> jdbc url\n"
0330: + " --user <name> username used for connection\n"
0331: + " --password <password> password for this user\n"
0332: + " --urlid <urlid> use url/user/password/driver in rc file\n"
0333: + " --rcfile <file> (defaults to 'dbmanager.rc' in home dir)\n"
0334: + " --dir <path> default directory\n"
0335: + " --script <file> reads from script file\n"
0336: + " --noexit do not call system.exit()\n"
0337: + "(Single-hypen switches like '-driver' are also supported)");
0338: }
0339:
0340: /**
0341: * Method declaration
0342: *
0343: */
0344: void insertTestData() {
0345:
0346: try {
0347: DatabaseManagerCommon.createTestTables(sStatement);
0348: refreshTree();
0349: txtCommand.setText(DatabaseManagerCommon
0350: .createTestData(sStatement));
0351: refreshTree();
0352:
0353: for (int i = 0; i < DatabaseManagerCommon.testDataSql.length; i++) {
0354: addToRecent(DatabaseManagerCommon.testDataSql[i]);
0355: }
0356:
0357: execute();
0358: } catch (SQLException e) {
0359: e.printStackTrace();
0360: }
0361: }
0362:
0363: /**
0364: * Method declaration
0365: *
0366: */
0367: public void main() {
0368:
0369: fMain = new Frame("HSQL Database Manager");
0370: imgEmpty = createImage(new MemoryImageSource(2, 2,
0371: new int[4 * 4], 2, 2));
0372:
0373: fMain.setIconImage(imgEmpty);
0374: fMain.addWindowListener(this );
0375:
0376: MenuBar bar = new MenuBar();
0377:
0378: // used shortcuts: CERGTSIUDOLM
0379: String[] fitems = { "-Connect...", "--", "-Open Script...",
0380: "-Save Script...", "-Save Result...",
0381: "-Save Result csv...", "--", "-Exit" };
0382:
0383: addMenu(bar, "File", fitems);
0384:
0385: String[] vitems = { "RRefresh Tree", "--", "GResults in Grid",
0386: "TResults in Text", "--", "1Shrink Tree",
0387: "2Enlarge Tree", "3Shrink Command", "4Enlarge Command" };
0388:
0389: addMenu(bar, "View", vitems);
0390:
0391: String[] sitems = { "SSELECT", "IINSERT", "UUPDATE", "DDELETE",
0392: "--", "-CREATE TABLE", "-DROP TABLE", "-CREATE INDEX",
0393: "-DROP INDEX", "--", "-CHECKPOINT", "-SCRIPT", "-SET",
0394: "-SHUTDOWN", "--", "-Test Script" };
0395:
0396: addMenu(bar, "Command", sitems);
0397:
0398: Menu recent = new Menu("Recent");
0399:
0400: mRecent = new Menu("Recent");
0401:
0402: bar.add(mRecent);
0403:
0404: String[] soptions = { "-AutoCommit on", "-AutoCommit off",
0405: "OCommit", "LRollback", "--", "-Disable MaxRows",
0406: "-Set MaxRows to 100", "--", "-Logging on",
0407: "-Logging off", "--", "-Insert test data" };
0408:
0409: addMenu(bar, "Options", soptions);
0410:
0411: String[] stools = { "-Dump", "-Restore", "-Transfer" };
0412:
0413: addMenu(bar, "Tools", stools);
0414:
0415: Menu hMenu = new Menu("Help");
0416: MenuItem aItem = new MenuItem("About");
0417:
0418: aItem.setShortcut(new MenuShortcut('A'));
0419: aItem.addActionListener(this );
0420: hMenu.add(aItem);
0421:
0422: MenuItem hItem = new MenuItem("Help");
0423:
0424: hItem.setShortcut(new MenuShortcut('H'));
0425: hItem.addActionListener(this );
0426: hMenu.add(hItem);
0427:
0428: //bar.add(hMenu);
0429: // Command above disabled only until a help display bug is fixed.
0430: fMain.setMenuBar(bar);
0431: fMain.setSize(640, 480);
0432: fMain.add("Center", this );
0433: initGUI();
0434:
0435: sRecent = new String[iMaxRecent];
0436:
0437: Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
0438: Dimension size = fMain.getSize();
0439:
0440: // (ulrivo): full size on screen with less than 640 width
0441: if (d.width >= 640) {
0442: fMain.setLocation((d.width - size.width) / 2,
0443: (d.height - size.height) / 2);
0444: } else {
0445: fMain.setLocation(0, 0);
0446: fMain.setSize(d);
0447: }
0448:
0449: fMain.show();
0450:
0451: // (ulrivo): load query from command line
0452: if (defScript != null) {
0453: if (defDirectory != null) {
0454: defScript = defDirectory + File.separator + defScript;
0455: }
0456:
0457: txtCommand.setText(DatabaseManagerCommon
0458: .readFile(defScript));
0459: }
0460:
0461: txtCommand.requestFocus();
0462: }
0463:
0464: /**
0465: * Method declaration
0466: *
0467: *
0468: * @param b
0469: * @param name
0470: * @param items
0471: */
0472: void addMenu(MenuBar b, String name, String[] items) {
0473:
0474: /* It's a very poor design to encapsulate menu creation this way.
0475: * Can't customize the menus this way (e.g. shortcut keys,
0476: * mnemonics, disabling, etc. */
0477: Menu menu = new Menu(name);
0478:
0479: if (name.equals("Tools") && !TT_AVAILABLE) {
0480:
0481: // Terrible place to do this. Forced to due to method design.
0482: menu.setEnabled(false);
0483: }
0484:
0485: addMenuItems(menu, items);
0486: b.add(menu);
0487: }
0488:
0489: /**
0490: * Method declaration
0491: *
0492: *
0493: * @param f
0494: * @param m
0495: */
0496: void addMenuItems(Menu f, String[] m) {
0497:
0498: for (int i = 0; i < m.length; i++) {
0499: MenuItem item = new MenuItem(m[i].substring(1));
0500: char c = m[i].charAt(0);
0501:
0502: if (c != '-') {
0503: item.setShortcut(new MenuShortcut(c));
0504: }
0505:
0506: item.addActionListener(this );
0507: f.add(item);
0508: }
0509: }
0510:
0511: /**
0512: * Method declaration
0513: *
0514: *
0515: * @param k
0516: */
0517: public void keyPressed(KeyEvent k) {
0518: }
0519:
0520: /**
0521: * Method declaration
0522: *
0523: *
0524: * @param k
0525: */
0526: public void keyReleased(KeyEvent k) {
0527: }
0528:
0529: /**
0530: * Method declaration
0531: *
0532: *
0533: * @param k
0534: */
0535: public void keyTyped(KeyEvent k) {
0536:
0537: if (k.getKeyChar() == '\n' && k.isControlDown()) {
0538: k.consume();
0539: execute();
0540: }
0541: }
0542:
0543: /**
0544: * Method declaration
0545: *
0546: *
0547: * @param ev
0548: */
0549: public void actionPerformed(ActionEvent ev) {
0550:
0551: String s = ev.getActionCommand();
0552:
0553: if (s == null) {
0554: if (ev.getSource() instanceof MenuItem) {
0555: MenuItem i;
0556:
0557: s = ((MenuItem) ev.getSource()).getLabel();
0558: }
0559: }
0560:
0561: if (s == null) {
0562: } else if (s.equals("Execute")) {
0563: execute();
0564: } else if (s.equals("Clear")) {
0565: clear();
0566: } else if (s.equals("Exit")) {
0567: windowClosing(null);
0568: } else if (s.equals("Transfer")) {
0569: Transfer.work(null);
0570: } else if (s.equals("Dump")) {
0571: Transfer.work(new String[] { "-d" });
0572: } else if (s.equals("Restore")) {
0573: Transfer.work(new String[] { "-r" });
0574: refreshTree();
0575: } else if (s.equals("Logging on")) {
0576: JavaSystem.setLogToSystem(true);
0577: } else if (s.equals("Logging off")) {
0578: JavaSystem.setLogToSystem(false);
0579: } else if (s.equals("Help")) {
0580: showHelp(new String[] { "", HELP_TEXT });
0581: } else if (s.equals("About")) {
0582: showHelp(new String[] { "", ABOUT_TEXT });
0583: } else if (s.equals("Refresh Tree")) {
0584: refreshTree();
0585: } else if (s.startsWith("#")) {
0586: int i = Integer.parseInt(s.substring(1));
0587:
0588: txtCommand.setText(sRecent[i]);
0589: } else if (s.equals("Connect...")) {
0590: connect(ConnectionDialog.createConnection(fMain, "Connect"));
0591: refreshTree();
0592: } else if (s.equals("Results in Grid")) {
0593: iResult = 0;
0594:
0595: pResult.removeAll();
0596: pResult.add("Center", gResult);
0597: pResult.doLayout();
0598: } else if (s.equals("Open Script...")) {
0599: FileDialog f = new FileDialog(fMain, "Open Script",
0600: FileDialog.LOAD);
0601:
0602: // (ulrivo): set default directory if set from command line
0603: if (defDirectory != null) {
0604: f.setDirectory(defDirectory);
0605: }
0606:
0607: f.show();
0608:
0609: String file = f.getFile();
0610:
0611: if (file != null) {
0612: StringBuffer buf = new StringBuffer();
0613:
0614: ifHuge = DatabaseManagerCommon.readFile(f
0615: .getDirectory()
0616: + file);
0617:
0618: if (4096 <= ifHuge.length()) {
0619: buf
0620: .append("This huge file cannot be edited. Please execute\n");
0621: txtCommand.setText(buf.toString());
0622: } else {
0623: txtCommand.setText(ifHuge);
0624: }
0625: }
0626: } else if (s.equals("Save Script...")) {
0627: FileDialog f = new FileDialog(fMain, "Save Script",
0628: FileDialog.SAVE);
0629:
0630: // (ulrivo): set default directory if set from command line
0631: if (defDirectory != null) {
0632: f.setDirectory(defDirectory);
0633: }
0634:
0635: f.show();
0636:
0637: String file = f.getFile();
0638:
0639: if (file != null) {
0640: DatabaseManagerCommon.writeFile(
0641: f.getDirectory() + file, txtCommand.getText());
0642: }
0643: } else if (s.equals("Save Result csv...")) {
0644: FileDialog f = new FileDialog(fMain, "Save Result CSV",
0645: FileDialog.SAVE);
0646:
0647: // (ulrivo): set default directory if set from command line
0648: if (defDirectory != null) {
0649: f.setDirectory(defDirectory);
0650: }
0651:
0652: f.show();
0653:
0654: String dir = f.getDirectory();
0655: String file = f.getFile();
0656:
0657: if (dir != null) {
0658: file = dir + "/" + file;
0659: }
0660:
0661: if (file != null) {
0662: showResultInText();
0663: saveAsCsv(file);
0664: }
0665: } else if (s.equals("Save Result...")) {
0666: FileDialog f = new FileDialog(fMain, "Save Result",
0667: FileDialog.SAVE);
0668:
0669: // (ulrivo): set default directory if set from command line
0670: if (defDirectory != null) {
0671: f.setDirectory(defDirectory);
0672: }
0673:
0674: f.show();
0675:
0676: String file = f.getFile();
0677:
0678: if (file != null) {
0679: showResultInText();
0680: DatabaseManagerCommon.writeFile(
0681: f.getDirectory() + file, txtResult.getText());
0682: }
0683: } else if (s.equals("Results in Text")) {
0684: iResult = 1;
0685:
0686: pResult.removeAll();
0687: pResult.add("Center", txtResult);
0688: pResult.doLayout();
0689: showResultInText();
0690: } else if (s.equals("AutoCommit on")) {
0691: try {
0692: cConn.setAutoCommit(true);
0693: } catch (SQLException e) {
0694: }
0695: } else if (s.equals("AutoCommit off")) {
0696: try {
0697: cConn.setAutoCommit(false);
0698: } catch (SQLException e) {
0699: }
0700: } else if (s.equals("Enlarge Tree")) {
0701: Dimension d = tTree.getMinimumSize();
0702:
0703: d.width += 20;
0704:
0705: tTree.setMinimumSize(d);
0706: fMain.pack();
0707: } else if (s.equals("Shrink Tree")) {
0708: Dimension d = tTree.getMinimumSize();
0709:
0710: d.width -= 20;
0711:
0712: if (d.width >= 0) {
0713: tTree.setMinimumSize(d);
0714: }
0715:
0716: fMain.pack();
0717: } else if (s.equals("Enlarge Command")) {
0718: txtCommand.setRows(txtCommand.getRows() + 1);
0719: fMain.pack();
0720: } else if (s.equals("Shrink Command")) {
0721: int i = txtCommand.getRows() - 1;
0722:
0723: txtCommand.setRows(i < 1 ? 1 : i);
0724: fMain.pack();
0725: } else if (s.equals("Commit")) {
0726: try {
0727: cConn.commit();
0728: } catch (SQLException e) {
0729: }
0730: } else if (s.equals("Insert test data")) {
0731: insertTestData();
0732: } else if (s.equals("Rollback")) {
0733: try {
0734: cConn.rollback();
0735: } catch (SQLException e) {
0736: }
0737: } else if (s.equals("Disable MaxRows")) {
0738: try {
0739: sStatement.setMaxRows(0);
0740: } catch (SQLException e) {
0741: }
0742: } else if (s.equals("Set MaxRows to 100")) {
0743: try {
0744: sStatement.setMaxRows(100);
0745: } catch (SQLException e) {
0746: }
0747: } else if (s.equals("SELECT")) {
0748: showHelp(DatabaseManagerCommon.selectHelp);
0749: } else if (s.equals("INSERT")) {
0750: showHelp(DatabaseManagerCommon.insertHelp);
0751: } else if (s.equals("UPDATE")) {
0752: showHelp(DatabaseManagerCommon.updateHelp);
0753: } else if (s.equals("DELETE")) {
0754: showHelp(DatabaseManagerCommon.deleteHelp);
0755: } else if (s.equals("CREATE TABLE")) {
0756: showHelp(DatabaseManagerCommon.createTableHelp);
0757: } else if (s.equals("DROP TABLE")) {
0758: showHelp(DatabaseManagerCommon.dropTableHelp);
0759: } else if (s.equals("CREATE INDEX")) {
0760: showHelp(DatabaseManagerCommon.createIndexHelp);
0761: } else if (s.equals("DROP INDEX")) {
0762: showHelp(DatabaseManagerCommon.dropIndexHelp);
0763: } else if (s.equals("CHECKPOINT")) {
0764: showHelp(DatabaseManagerCommon.checkpointHelp);
0765: } else if (s.equals("SCRIPT")) {
0766: showHelp(DatabaseManagerCommon.scriptHelp);
0767: } else if (s.equals("SHUTDOWN")) {
0768: showHelp(DatabaseManagerCommon.shutdownHelp);
0769: } else if (s.equals("SET")) {
0770: showHelp(DatabaseManagerCommon.setHelp);
0771: } else if (s.equals("Test Script")) {
0772: showHelp(DatabaseManagerCommon.testHelp);
0773: }
0774: }
0775:
0776: /**
0777: * Method declaration
0778: *
0779: *
0780: * @param s
0781: * @param help
0782: */
0783: void showHelp(String[] help) {
0784:
0785: txtCommand.setText(help[0]);
0786: txtResult.setText(help[1]);
0787:
0788: bHelp = true;
0789:
0790: pResult.removeAll();
0791: pResult.add("Center", txtResult);
0792: pResult.doLayout();
0793: txtCommand.requestFocus();
0794: txtCommand.setCaretPosition(help[0].length());
0795: }
0796:
0797: /**
0798: * Method declaration
0799: *
0800: *
0801: * @param e
0802: */
0803: public void windowActivated(WindowEvent e) {
0804: }
0805:
0806: /**
0807: * Method declaration
0808: *
0809: *
0810: * @param e
0811: */
0812: public void windowDeactivated(WindowEvent e) {
0813: }
0814:
0815: /**
0816: * Method declaration
0817: *
0818: *
0819: * @param e
0820: */
0821: public void windowClosed(WindowEvent e) {
0822: }
0823:
0824: /**
0825: * Method declaration
0826: *
0827: *
0828: * @param ev
0829: */
0830: public void windowClosing(WindowEvent ev) {
0831:
0832: try {
0833: cConn.close();
0834: } catch (Exception e) {
0835: }
0836:
0837: fMain.dispose();
0838:
0839: if (bMustExit) {
0840: System.exit(0);
0841: }
0842: }
0843:
0844: /**
0845: * Method declaration
0846: *
0847: *
0848: * @param e
0849: */
0850: public void windowDeiconified(WindowEvent e) {
0851: }
0852:
0853: /**
0854: * Method declaration
0855: *
0856: *
0857: * @param e
0858: */
0859: public void windowIconified(WindowEvent e) {
0860: }
0861:
0862: /**
0863: * Method declaration
0864: *
0865: *
0866: * @param e
0867: */
0868: public void windowOpened(WindowEvent e) {
0869: }
0870:
0871: /**
0872: * Method declaration
0873: * Clear SQL Statements.
0874: */
0875: void clear() {
0876:
0877: ifHuge = "";
0878:
0879: txtCommand.setText(ifHuge);
0880: }
0881:
0882: /**
0883: * Method declaration
0884: * Adjust this method for large strings...ie multi megabtypes.
0885: */
0886: void execute() {
0887:
0888: String sCmd = null;
0889:
0890: if (4096 <= ifHuge.length()) {
0891: sCmd = ifHuge;
0892: } else {
0893: sCmd = txtCommand.getText();
0894: }
0895:
0896: if (sCmd.startsWith("-->>>TEST<<<--")) {
0897: testPerformance();
0898:
0899: return;
0900: }
0901:
0902: String[] g = new String[1];
0903:
0904: lTime = System.currentTimeMillis();
0905:
0906: try {
0907: sStatement.execute(sCmd);
0908:
0909: lTime = System.currentTimeMillis() - lTime;
0910:
0911: int r = sStatement.getUpdateCount();
0912:
0913: if (r == -1) {
0914: formatResultSet(sStatement.getResultSet());
0915: } else {
0916: g[0] = "update count";
0917:
0918: gResult.setHead(g);
0919:
0920: g[0] = String.valueOf(r);
0921:
0922: gResult.addRow(g);
0923: }
0924:
0925: addToRecent(txtCommand.getText());
0926: } catch (SQLException e) {
0927: lTime = System.currentTimeMillis() - lTime;
0928: g[0] = "SQL Error";
0929:
0930: gResult.setHead(g);
0931:
0932: String s = e.getMessage();
0933:
0934: s += " / Error Code: " + e.getErrorCode();
0935: s += " / State: " + e.getSQLState();
0936: g[0] = s;
0937:
0938: gResult.addRow(g);
0939: }
0940:
0941: updateResult();
0942: System.gc();
0943: }
0944:
0945: /**
0946: * Method declaration
0947: *
0948: */
0949: void updateResult() {
0950:
0951: if (iResult == 0) {
0952:
0953: // in case 'help' has removed the grid
0954: if (bHelp) {
0955: pResult.removeAll();
0956: pResult.add("Center", gResult);
0957: pResult.doLayout();
0958:
0959: bHelp = false;
0960: }
0961:
0962: gResult.update();
0963: gResult.repaint();
0964: } else {
0965: showResultInText();
0966: }
0967:
0968: txtCommand.selectAll();
0969: txtCommand.requestFocus();
0970: }
0971:
0972: /**
0973: * Method declaration
0974: *
0975: *
0976: * @param r
0977: */
0978: void formatResultSet(ResultSet r) {
0979:
0980: if (r == null) {
0981: String[] g = new String[1];
0982:
0983: g[0] = "Result";
0984:
0985: gResult.setHead(g);
0986:
0987: g[0] = "(empty)";
0988:
0989: gResult.addRow(g);
0990:
0991: return;
0992: }
0993:
0994: try {
0995: ResultSetMetaData m = r.getMetaData();
0996: int col = m.getColumnCount();
0997: String[] h = new String[col];
0998:
0999: for (int i = 1; i <= col; i++) {
1000: h[i - 1] = m.getColumnLabel(i);
1001: }
1002:
1003: gResult.setHead(h);
1004:
1005: while (r.next()) {
1006: for (int i = 1; i <= col; i++) {
1007: try {
1008: h[i - 1] = r.getString(i);
1009:
1010: if (r.wasNull()) {
1011: h[i - 1] = "(null)";
1012: }
1013: } catch (SQLException e) {
1014: }
1015: }
1016:
1017: gResult.addRow(h);
1018: }
1019:
1020: r.close();
1021: } catch (SQLException e) {
1022: }
1023: }
1024:
1025: /**
1026: * Method declaration
1027: *
1028: */
1029: void testPerformance() {
1030:
1031: String all = txtCommand.getText();
1032: StringBuffer b = new StringBuffer();
1033: long total = 0;
1034:
1035: for (int i = 0; i < all.length(); i++) {
1036: char c = all.charAt(i);
1037:
1038: if (c != '\n') {
1039: b.append(c);
1040: }
1041: }
1042:
1043: all = b.toString();
1044:
1045: String[] g = new String[4];
1046:
1047: g[0] = "ms";
1048: g[1] = "count";
1049: g[2] = "sql";
1050: g[3] = "error";
1051:
1052: gResult.setHead(g);
1053:
1054: int max = 1;
1055:
1056: lTime = System.currentTimeMillis() - lTime;
1057:
1058: while (!all.equals("")) {
1059: int i = all.indexOf(';');
1060: String sql;
1061:
1062: if (i != -1) {
1063: sql = all.substring(0, i);
1064: all = all.substring(i + 1);
1065: } else {
1066: sql = all;
1067: all = "";
1068: }
1069:
1070: if (sql.startsWith("--#")) {
1071: max = Integer.parseInt(sql.substring(3));
1072:
1073: continue;
1074: } else if (sql.startsWith("--")) {
1075: continue;
1076: }
1077:
1078: g[2] = sql;
1079:
1080: long l = 0;
1081:
1082: try {
1083: l = DatabaseManagerCommon.testStatement(sStatement,
1084: sql, max);
1085: total += l;
1086: g[0] = String.valueOf(l);
1087: g[1] = String.valueOf(max);
1088: g[3] = "";
1089: } catch (SQLException e) {
1090: g[0] = g[1] = "n/a";
1091: g[3] = e.toString();
1092: }
1093:
1094: gResult.addRow(g);
1095: System.out.println(l + " ms : " + sql);
1096: }
1097:
1098: g[0] = "" + total;
1099: g[1] = "total";
1100: g[2] = "";
1101:
1102: gResult.addRow(g);
1103:
1104: lTime = System.currentTimeMillis() - lTime;
1105:
1106: updateResult();
1107: }
1108:
1109: void saveAsCsv(String filename) {
1110:
1111: try {
1112: File file = new File(filename);
1113: CSVWriter writer = new CSVWriter(file, null);
1114: String[] col = gResult.getHead();
1115: int width = col.length;
1116: Vector data = gResult.getData();
1117: String[] row;
1118: int height = data.size();
1119:
1120: writer.writeHeader(col);
1121:
1122: for (int i = 0; i < height; i++) {
1123: row = (String[]) data.elementAt(i);
1124:
1125: String[] myRow = new String[row.length];
1126:
1127: for (int j = 0; j < row.length; j++) {
1128: String r = row[j];
1129:
1130: if (r.equals("(null)")) {
1131:
1132: // null is formatted as (null)
1133: r = "";
1134: }
1135:
1136: myRow[j] = r;
1137: }
1138:
1139: writer.writeData(myRow);
1140: }
1141:
1142: writer.close();
1143: } catch (IOException e) {
1144: throw new RuntimeException("IOError: " + e.getMessage());
1145: }
1146: }
1147:
1148: /**
1149: * Method declaration
1150: *
1151: */
1152: void showResultInText() {
1153:
1154: String[] col = gResult.getHead();
1155: int width = col.length;
1156: int[] size = new int[width];
1157: Vector data = gResult.getData();
1158: String[] row;
1159: int height = data.size();
1160:
1161: for (int i = 0; i < width; i++) {
1162: size[i] = col[i].length();
1163: }
1164:
1165: for (int i = 0; i < height; i++) {
1166: row = (String[]) data.elementAt(i);
1167:
1168: for (int j = 0; j < width; j++) {
1169: int l = row[j].length();
1170:
1171: if (l > size[j]) {
1172: size[j] = l;
1173: }
1174: }
1175: }
1176:
1177: StringBuffer b = new StringBuffer();
1178:
1179: for (int i = 0; i < width; i++) {
1180: b.append(col[i]);
1181:
1182: for (int l = col[i].length(); l <= size[i]; l++) {
1183: b.append(' ');
1184: }
1185: }
1186:
1187: b.append(NL);
1188:
1189: for (int i = 0; i < width; i++) {
1190: for (int l = 0; l < size[i]; l++) {
1191: b.append('-');
1192: }
1193:
1194: b.append(' ');
1195: }
1196:
1197: b.append(NL);
1198:
1199: for (int i = 0; i < height; i++) {
1200: row = (String[]) data.elementAt(i);
1201:
1202: for (int j = 0; j < width; j++) {
1203: b.append(row[j]);
1204:
1205: for (int l = row[j].length(); l <= size[j]; l++) {
1206: b.append(' ');
1207: }
1208: }
1209:
1210: b.append(NL);
1211: }
1212:
1213: b.append(NL + height + " row(s) in " + lTime + " ms");
1214: txtResult.setText(b.toString());
1215: }
1216:
1217: /**
1218: * Method declaration
1219: *
1220: *
1221: * @param s
1222: */
1223: private void addToRecent(String s) {
1224:
1225: for (int i = 0; i < iMaxRecent; i++) {
1226: if (s.equals(sRecent[i])) {
1227: return;
1228: }
1229: }
1230:
1231: if (sRecent[iRecent] != null) {
1232: mRecent.remove(iRecent);
1233: }
1234:
1235: sRecent[iRecent] = s;
1236:
1237: if (s.length() > 43) {
1238: s = s.substring(0, 40) + "...";
1239: }
1240:
1241: MenuItem item = new MenuItem(s);
1242:
1243: item.setActionCommand("#" + iRecent);
1244: item.addActionListener(this );
1245: mRecent.insert(item, iRecent);
1246:
1247: iRecent = (iRecent + 1) % iMaxRecent;
1248: }
1249:
1250: /**
1251: * Method declaration
1252: *
1253: */
1254: private void initGUI() {
1255:
1256: Panel pQuery = new Panel();
1257: Panel pCommand = new Panel();
1258:
1259: pResult = new Panel();
1260:
1261: pQuery.setLayout(new BorderLayout());
1262: pCommand.setLayout(new BorderLayout());
1263: pResult.setLayout(new BorderLayout());
1264:
1265: Font fFont = new Font("Dialog", Font.PLAIN, 12);
1266:
1267: txtCommand = new TextArea(5, 40);
1268:
1269: txtCommand.addKeyListener(this );
1270:
1271: txtResult = new TextArea(20, 40);
1272:
1273: txtCommand.setFont(fFont);
1274: txtResult.setFont(new Font("Courier", Font.PLAIN, 12));
1275:
1276: butExecute = new Button("Execute");
1277: butClear = new Button("Clear");
1278:
1279: butExecute.addActionListener(this );
1280: butClear.addActionListener(this );
1281: pCommand.add("East", butExecute);
1282: pCommand.add("West", butClear);
1283: pCommand.add("Center", txtCommand);
1284:
1285: gResult = new Grid();
1286:
1287: setLayout(new BorderLayout());
1288: pResult.add("Center", gResult);
1289: pQuery.add("North", pCommand);
1290: pQuery.add("Center", pResult);
1291: fMain.add("Center", pQuery);
1292:
1293: tTree = new Tree();
1294:
1295: // (ulrivo): screen with less than 640 width
1296: Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
1297:
1298: if (d.width >= 640) {
1299: tTree.setMinimumSize(new Dimension(200, 100));
1300: } else {
1301: tTree.setMinimumSize(new Dimension(80, 100));
1302: }
1303:
1304: gResult.setMinimumSize(new Dimension(200, 300));
1305: fMain.add("West", tTree);
1306: doLayout();
1307: fMain.pack();
1308: }
1309:
1310: /**
1311: * Method declaration
1312: *
1313: */
1314: protected void refreshTree() {
1315:
1316: tTree.removeAll();
1317:
1318: try {
1319: int color_table = Color.yellow.getRGB();
1320: int color_column = Color.orange.getRGB();
1321: int color_index = Color.red.getRGB();
1322:
1323: tTree.addRow("", dMeta.getURL(), "-", 0);
1324:
1325: String[] usertables = { "TABLE", "GLOBAL TEMPORARY", "VIEW" };
1326:
1327: // fredt@users Schema support
1328: Vector schemas = new Vector();
1329: Vector tables = new Vector();
1330:
1331: // sqlbob@users Added remarks.
1332: Vector remarks = new Vector();
1333: ResultSet result = dMeta.getTables(null, null, null,
1334: usertables);
1335:
1336: try {
1337: while (result.next()) {
1338: schemas.addElement(result.getString(2));
1339: tables.addElement(result.getString(3));
1340: remarks.addElement(result.getString(5));
1341: }
1342: } finally {
1343: result.close();
1344: }
1345:
1346: for (int i = 0; i < tables.size(); i++) {
1347: String name = (String) tables.elementAt(i);
1348: String schema = (String) schemas.elementAt(i);
1349: String key = "tab-" + name + "-";
1350:
1351: tTree.addRow(key, name, "+", color_table);
1352:
1353: // sqlbob@users Added remarks.
1354: String remark = (String) remarks.elementAt(i);
1355:
1356: if ((schema != null) && !schema.trim().equals("")) {
1357: tTree.addRow(key + "s", "schema: " + schema);
1358: }
1359:
1360: if ((remark != null) && !remark.trim().equals("")) {
1361: tTree.addRow(key + "r", " " + remark);
1362: }
1363:
1364: ResultSet col = dMeta.getColumns(null, schema, name,
1365: null);
1366:
1367: try {
1368: while (col.next()) {
1369: String c = col.getString(4);
1370: String k1 = key + "col-" + c + "-";
1371:
1372: tTree.addRow(k1, c, "+", color_column);
1373:
1374: String type = col.getString(6);
1375:
1376: tTree.addRow(k1 + "t", "Type: " + type);
1377:
1378: boolean nullable = col.getInt(11) != DatabaseMetaData.columnNoNulls;
1379:
1380: tTree.addRow(k1 + "n", "Nullable: " + nullable);
1381: }
1382: } finally {
1383: col.close();
1384: }
1385:
1386: tTree.addRow(key + "ind", "Indices", "+", 0);
1387:
1388: ResultSet ind = dMeta.getIndexInfo(null, schema, name,
1389: false, false);
1390: String oldiname = null;
1391:
1392: try {
1393: while (ind.next()) {
1394: boolean nonunique = ind.getBoolean(4);
1395: String iname = ind.getString(6);
1396: String k2 = key + "ind-" + iname + "-";
1397:
1398: if ((oldiname == null || !oldiname
1399: .equals(iname))) {
1400: tTree.addRow(k2, iname, "+", color_index);
1401: tTree.addRow(k2 + "u", "Unique: "
1402: + !nonunique);
1403:
1404: oldiname = iname;
1405: }
1406:
1407: String c = ind.getString(9);
1408:
1409: tTree.addRow(k2 + "c-" + c + "-", c);
1410: }
1411: } finally {
1412: ind.close();
1413: }
1414: }
1415:
1416: tTree.addRow("p", "Properties", "+", 0);
1417: tTree.addRow("pu", "User: " + dMeta.getUserName());
1418: tTree.addRow("pr", "ReadOnly: " + cConn.isReadOnly());
1419: tTree.addRow("pa", "AutoCommit: " + cConn.getAutoCommit());
1420: tTree.addRow("pd", "Driver: " + dMeta.getDriverName());
1421: tTree.addRow("pp", "Product: "
1422: + dMeta.getDatabaseProductName());
1423: tTree.addRow("pv", "Version: "
1424: + dMeta.getDatabaseProductVersion());
1425: } catch (SQLException e) {
1426: tTree.addRow("", "Error getting metadata:", "-", 0);
1427: tTree.addRow("-", e.getMessage());
1428: tTree.addRow("-", e.getSQLState());
1429: }
1430:
1431: tTree.update();
1432: }
1433: }
|