001/* 002 * CreateDBTables.java 003 * Copyright (c) 2002 Tom B. Gutwin P.Eng. 004 * 005 * This program is free software; you can redistribute it and/or 006 * modify it under the terms of the GNU General Public License 007 * as published by the Free Software Foundation; either version 2 008 * of the License, or any later version. 009 * 010 * This program is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 013 * GNU General Public License for more details. 014 * 015 * You should have received a copy of the GNU General Public License 016 * along with this program; if not, write to the Free Software 017 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 018 */ 019 020package ca.bc.webarts.tools; 021 022import ca.bc.webarts.widgets.WrapperApp; 023import java.io.*; 024 025import java.sql.*; 026import javax.swing.*; 027import javax.swing.event.*; 028 029 030 031/** 032 * A class to help build a whack of db tables based on a txt file.<BR /> 033 * This App Gets called like: java ca.bc.webarts.tools.CreateDBTables -test 034 * false -f IEEEDBTables.txt IEEEVANC 035 * 036 * @author tgutwin 037 * @created July 8, 2002 038 */ 039 040public class CreateDBTables extends JApplet 041{ 042 043 /** **/ 044 static int dbIndex = 1; 045 /** */ 046 final static String[] jdbcDriverName = {"org.postgresql.Driver", 047 "COM.ibm.db2.jdbc.app.DB2Driver", 048 "org.postgresql.Driver"}; 049 /** */ 050 private static String[] dbBrandName = {"PostgreSQL","DB2","PostgreSQL"}; 051 /** */ 052 private static String[] dbServerName = {"warp2","Aurora1","warp2"}; 053 /** */ 054 private static String[] dbServerPort = {"5432","6790","5432"}; 055 /** */ 056 private static String[] dbName = {"test","sample","test"}; 057 /** */ 058 private static String[] dbUserId = {"tgutwin","tgutwin","tgutwin"}; 059 /** */ 060 private static String[] dbUserPassword = {"18BoogieWoogie", 061 "GetYourOwnPassword", 062 "18BoogieWoogie"}; 063 /** */ 064 private static String[] dbURL = { 065 "jdbc:postgresql://" + dbServerName[0] + ":" + dbServerPort[0] + "/" + dbName[0], 066 "jdbc:db2://" + dbServerName[1] + ":" + dbServerPort[1] + "/" + dbName[1], 067 "jdbc:postgresql://" + dbServerName[2] + ":" + dbServerPort[2] + "/" + dbName[2]}; 068 /** */ 069 final static String adminEmail = "webadmin@webarts.bc.ca"; 070 /** */ 071 final static String adminEmailURL = "<A HREF=\"" + adminEmail + "\">" + adminEmail + "</A>"; 072 /** */ 073 final static String jdbcDriverErrorMsg = "Sorry, a JDBC Driver ERROR occurred. I won't be able to process you request"; 074 /** */ 075 final static String sqlErrorMsg = "Sorry, a SQL ERROR occurred. I won't be able to process your request"; 076 /** */ 077 final static String reportErrorMsg = "Please copy the follwing information and email it to " + adminEmail; 078 /** */ 079 final static String fileErrorMsg = "File Error"; 080 /** */ 081 static short numColumns = 0; 082 /** */ 083 String tableNm_; 084 /** */ 085 String testTableName = "testTable"; 086 /** */ 087 String[][] tableColumns; 088 /** 089 * A flag to specify if the DROP command was specified on the commandline. If 090 * this is true the tablename that is specified will be dropped from the DB. 091 */ 092 boolean dropTable = false; 093 094 /** 095 * A flag to specify if the f command was specified on the commandline. If 096 * this is true the a input filename was specified on the commandline that 097 * will be used to get the table info from. 098 */ 099 boolean fileArgFlag = false; 100 101 /** 102 * The filename that is specified on the commandline in conjunction with the 103 * -f switch 104 */ 105 String inFileName = "testTable.txt"; 106 107 /** */ 108 Connection con = null; 109 /** 110 * Input <code>File</code> to read in the formname/dbtablecolumnname at 111 * runtime. 112 */ 113 FileReader fileReader = null; 114 /** Tokenized version of the input config file <code>fileReader</code> */ 115 StreamTokenizer inputTokens; 116 117 /** */ 118 static boolean DEBUG = true; 119 120 /** Description of the Field */ 121 static String[] inArgs; 122 123 /* 124 static 125 { 126 try 127 { 128 Class.forName(jdbcDriverName[0]); 129 System.out.println("We Registered The Driver!"); 130 } 131 catch (Exception e) 132 { 133 System.out.println(jdbcDriverErrorMsg); 134 System.out.println(e); 135 System.out.println(reportErrorMsg); 136 System.exit(1); 137 } 138 } 139 */ 140 141 142 /** 143 * the method that return the programmers customized information about this 144 * applet. 145 * 146 * @return The appletInfo value 147 */ 148 public String getAppletInfo() 149 { 150 return "Database Table Creator, Copyright (c) WebARTS Design 2000 - Tom Gutwin P.Eng."; 151 } 152 153 154 /** 155 * the method that returns the information about the possible applet 156 * parameters. 157 * 158 * @return a table of Strings (String[][]) holding the input param name, 159 * type and description 160 */ 161 public String[][] getParameterInfo() 162 { 163 String[][] retVal = { 164 {"INPUTFILE", 165 "String", 166 "the string holding the filename to read the table data "} 167 }; 168 return retVal; 169 } 170 171 172 /** 173 * Initializes everything needed to start/run this applet. It gets called 174 * upon 1st call of the applet. It performs the following initializations: 175 * 176 * <UL> 177 * <LI> <B>retrieves the codebase</B> 178 * <LI> <B>retrieves the applet input parameters</B> 179 * <LI> <B>sets the look and feel attribute</B> 180 * </UL> 181 * 182 */ 183 public void init() 184 { 185 setVisible(false); 186 187 /* 188 * get the JApplets root pane & make a fix so this applet does not crash NS or IE 189 */ 190 JRootPane rp = getRootPane(); 191 rp.putClientProperty("defeatSystemEventQueueCheck", Boolean.TRUE); 192 193 TableCreator(inArgs); 194 } 195 196 197 /** 198 * @param numSwitches Description of the Parameter 199 * @param switchArgs Description of the Parameter 200 * @return Description of the Return Value 201 */ 202 private boolean parseSwitches(int numSwitches, String[][] switchArgs) 203 { 204 boolean retVal = true; 205 for (int i = 0; i < numSwitches; i++) 206 { 207 if (switchArgs[i][0].equals("-f")) 208 { 209 inFileName = switchArgs[i][1]; 210 fileArgFlag = true; 211 } 212 if (switchArgs[i][0].equals("-test")) 213 { 214 if (switchArgs[i][1].equals("true")) 215 { 216 DEBUG = true; 217 } 218 else 219 { 220 DEBUG = false; 221 } 222 } 223 } 224 return retVal; 225 } 226 227 228 /** 229 * @return Description of the Return Value 230 */ 231 private boolean initFileTokens() 232 { 233 boolean retVal = true; 234 235 try 236 { 237 System.out.println("Tokenizing file " + inFileName); 238 fileReader = new FileReader(inFileName); 239 240 inputTokens = new StreamTokenizer(fileReader); 241 inputTokens.eolIsSignificant(true); 242 inputTokens.lowerCaseMode(true); 243 inputTokens.slashSlashComments(true); 244 inputTokens.slashStarComments(true); 245 } 246 catch (FileNotFoundException e) 247 { 248 System.err.println(fileErrorMsg); 249 System.err.println(reportErrorMsg); 250 System.err.println("e.printStackTrace()"); 251 retVal = false; 252 } 253 catch (java.lang.NullPointerException e) 254 { 255 System.err.println(fileErrorMsg); 256 System.err.println(reportErrorMsg); 257 System.err.println("e.printStackTrace()"); 258 retVal = false; 259 } 260 261 return retVal; 262 } 263 264 265 /** 266 * Reads one token from the inputTokens, if it is a StreamTokenizer.TT_WORD 267 * it is assumed to be the next table name and puts it in the class tableNm_ 268 * field. 269 * 270 * @return false if success, true if at EOF 271 */ 272 private boolean getNextTableName() 273 { 274 //returns true if atEOF 275 boolean retVal = false; 276 String tempStr = ""; 277 tableNm_ = testTableName; 278 int tempResult = 0; 279 280 try 281 { 282 tempResult = inputTokens.nextToken(); 283 if (tempResult == StreamTokenizer.TT_WORD) 284 { 285 tempStr = inputTokens.sval; 286 System.out.println("Next Table=" + tempStr); 287 tempResult = inputTokens.nextToken(); 288 // read the EOL 289 } 290 else 291 { 292 // if(tempResult == StreamTokenizer.TT_EOF) 293 retVal = true; 294 } 295 296 } 297 catch (IOException ex) 298 { 299 System.err.println(fileErrorMsg); 300 System.err.println(reportErrorMsg); 301 System.err.println("getNextTableName reading file:" + inFileName); 302 retVal = true; 303 } 304 tableNm_ = tempStr; 305 return retVal; 306 } 307 308 309 /** 310 * A method to fill the <code>tableColumns</code> static array with the 311 * column information. This information goes directly into the SQL statement 312 * that is used to create the table. 313 * 314 * @return The nextTable value 315 */ 316 private short getNextTable() 317 { 318 numColumns = 0; 319 tableColumns = new String[250][3]; 320 tableColumns[0][0] = "Column1"; 321 tableColumns[0][1] = "SMALLINT"; 322 tableColumns[0][2] = "NOT NULL"; 323 324 int tempResult = 0; 325 int numFields = 0; 326 327 System.out.println("Getting Table Column data..."); 328 try 329 { 330 do // while not(EOF, NUMBER) 331 { 332 System.out.println("Col #"+numColumns); 333 do // while not(EOL,EOF, NUMBER) 334 { 335 System.out.println("Col - "+numColumns); 336 tempResult = inputTokens.nextToken(); 337 if (tempResult == StreamTokenizer.TT_WORD) 338 { 339 if (inputTokens.sval.trim().equals("notnull")) 340 { 341 tableColumns[numColumns][numFields++] = "NOT NULL"; 342 } 343 344 // CHAR 345 else if (inputTokens.sval.equals("char") || inputTokens.sval.equals("varchar")) 346 { 347 tableColumns[numColumns][numFields] = inputTokens.sval; 348 tempResult = inputTokens.nextToken(); 349 if (tempResult == StreamTokenizer.TT_NUMBER) 350 { 351 tableColumns[numColumns][numFields++] += "(" + inputTokens.nval + ")"; 352 tempResult = inputTokens.nextToken(); 353 } 354 else 355 { 356 tableColumns[numColumns][numFields++] += "(254)"; 357 } 358 } 359 360 // datalink URL 361 else if (inputTokens.sval.equals("datalink")) 362 { 363 tableColumns[numColumns][numFields++] = inputTokens.sval + " LINKTYPE URL "; 364 } 365 366 // CLOB 367 else if (inputTokens.sval.equals("clob")) 368 { 369 tableColumns[numColumns][numFields] = inputTokens.sval; 370 tempResult = inputTokens.nextToken(); 371 if (tempResult == StreamTokenizer.TT_NUMBER) 372 { 373 tableColumns[numColumns][numFields++] += "(" + new Integer((int) inputTokens.nval) + " K)"; 374 tempResult = inputTokens.nextToken(); 375 } 376 else 377 { 378 tableColumns[numColumns][numFields++] += "(500 K)"; 379 } 380 } 381 else 382 { 383 tableColumns[numColumns][numFields++] = inputTokens.sval; 384 } 385 } 386 } while ( !(tempResult == StreamTokenizer.TT_NUMBER) && 387 tempResult != StreamTokenizer.TT_EOL && 388 tempResult != StreamTokenizer.TT_EOF); 389 numFields = 0; 390 numColumns++; 391 } while (!(tempResult == StreamTokenizer.TT_NUMBER) && 392 tempResult != StreamTokenizer.TT_EOF); 393 if (tempResult == StreamTokenizer.TT_NUMBER) 394 { 395 tempResult = inputTokens.nextToken(); 396 // read and discard the next EOL 397 numColumns--; 398 } 399 400 } 401 catch (IOException ex) 402 { 403 System.err.println(fileErrorMsg); 404 System.err.println(reportErrorMsg); 405 System.err.println("getNextTable reading file:" + inFileName); 406 } 407 return numColumns; 408 } 409 410 411 /** 412 * @param table Description of the Parameter 413 * @param cols Description of the Parameter 414 * @param numCols Description of the Parameter 415 * @return Description of the Return Value 416 */ 417 private boolean createTable(String table, String[][] cols, short numCols) 418 { 419 420 String sqlString; 421 String columnString = ""; 422 boolean retVal = true; 423 424 for (int i = 0; i < numCols; i++) 425 { 426 if (cols[i][1] == null) 427 { 428 cols[i][1] = "SMALLINT"; 429 } 430 if (cols[i][2] == null) 431 { 432 cols[i][2] = " "; 433 } 434 } 435 436 for (int i = 0; i < numCols; i++) 437 { 438 columnString += cols[i][0] + " " + cols[i][1] + " " + cols[i][2]; 439 if (i + 1 < numCols) 440 { 441 columnString += ",\n"; 442 } 443 } 444 sqlString = "CREATE TABLE " + table + " ( \n" + columnString + ",\nPrimary KEY(" + cols[0][0] + ") \n)"; 445 446 if (!DEBUG) 447 { 448 try 449 { 450 Statement stmt = con.createStatement(); 451 452 ResultSet rs; 453 System.out.println("ExecutingSQL = " + sqlString); 454 rs = stmt.executeQuery(sqlString); 455 456 rs.close(); 457 stmt.close(); 458 459 } 460 catch (SQLException e) 461 { 462 System.err.println(sqlErrorMsg); 463 System.err.println(reportErrorMsg); 464 System.err.println(e.toString()); 465 System.err.println("Puked While Creating Table:" + table); 466 // e.printStackTrace(); 467 retVal = false; 468 } 469 } 470 else 471 { 472 System.out.println("SQL = " + sqlString); 473 } 474 return retVal; 475 } 476 477 478 /** 479 * Constructor. 480 * 481 * @param argv Description of the Parameter 482 */ 483 public void TableCreator(String argv[]) 484 { 485 boolean switchError = false; 486 487 /* 488 * get the commandline parms 489 */ 490 switch (argv.length) 491 { 492 case 0: 493 dbIndex = 0; 494 //dbName[0] = "sample"; 495 System.out.println("NO Commandline DB specified. Using -->" + 496 dbName[dbIndex]); 497 break; 498 499 case 1: 500 /* 501 * database name 502 */ 503 dbName[0] = argv[0]; 504 System.out.println("Using DB -->" + dbName[0]); 505 break; 506 507 case 2: 508 /* 509 * -DROP database name 510 */ 511 if (!argv[0].equals("-DROP")) 512 { 513 switchError = true; 514 } 515 dropTable = true; 516 dbName[0] = argv[argv.length - 1]; 517 System.out.println("Using DB -->" + dbName[0]); 518 break; 519 520 default: 521 /* 522 * get the command switches 523 */ 524 String[][] switches = new String[argv.length][2]; 525 int i = 0; 526 int k = 0; 527 while (i < argv.length - 1) 528 { 529 switches[k][0] = argv[i++]; 530 switches[k++][1] = argv[i++]; 531 } 532 parseSwitches((int) ((argv.length - 1) / 2), switches); 533 dbName[0] = argv[argv.length - 1]; 534 System.out.println("Using DB -->" + dbName[0]); 535 } 536 537 try 538 { 539 Class.forName(jdbcDriverName[dbIndex]); 540 System.out.println("We Registered The Driver!"); 541 542 543 // construct the URL ( sample is the database name ) 544 boolean tableCreated = true; 545 boolean atEOF = false; 546 // connect to database with userid and password 547 System.out.println("Connecting:"); 548 System.out.println(" "+dbURL[dbIndex]); 549 System.out.println(" "+dbUserId[dbIndex]); 550 con = DriverManager.getConnection(dbURL[dbIndex], dbUserId[dbIndex], dbUserPassword[dbIndex]); 551 System.out.println("Connected."); 552 553 if (!con.isClosed()) 554 { 555 /* 556 * read the nput file to get the next Itablename and columns 557 */ 558 initFileTokens(); 559 560 while (!atEOF && tableCreated) 561 { 562 563 atEOF = getNextTableName(); 564 numColumns = getNextTable(); 565 tableCreated = false; 566 if (!atEOF && tableNm_.length() > 0 && numColumns > 0) 567 { 568 tableCreated = createTable(tableNm_, tableColumns, numColumns); 569 } 570 else 571 { 572 if (!atEOF) 573 { 574 System.err.println(fileErrorMsg); 575 System.err.println(reportErrorMsg); 576 System.err.println("DBName = " + dbName + ", " + "Table Name =" + tableNm_ + ", " + numColumns + " columns."); 577 atEOF = true; 578 } 579 } 580 581 if (tableCreated && !DEBUG) 582 { 583 // retrieve data from the database 584 System.out.println("Retrieve some data from the database..."); 585 Statement stmt = con.createStatement(); 586 ResultSet rs = stmt.executeQuery("SELECT * from " + tableNm_); 587 588 System.out.println("Received results:"); 589 590 // display the result set 591 // rs.next() returns false when there are no more rows 592 while (rs.next()) 593 { 594 String a = rs.getString(1); 595 596 System.out.print(" entry= " + a); 597 System.out.print("\n"); 598 } 599 System.out.print("---------------------\n"); 600 601 rs.close(); 602 stmt.close(); 603 con.commit(); 604 } 605 else 606 { 607 if (!DEBUG) 608 { 609 con.rollback(); 610 } 611 } 612 613 } 614 con.close(); 615 616 } 617 else 618 { 619 System.err.println("Lost the DB Connection"); 620 System.err.println(reportErrorMsg); 621 System.exit(1); 622 } 623 } 624 catch (SecurityException e) 625 { 626 System.err.println("Input File is Not Readable"); 627 System.err.println(reportErrorMsg); 628 e.printStackTrace(System.err); 629 } 630 catch (SQLException e) 631 { 632 System.err.println(sqlErrorMsg); 633 System.err.println(reportErrorMsg); 634 e.printStackTrace(System.err); 635 636 } 637 catch (Exception e) 638 { 639 System.out.println(jdbcDriverErrorMsg); 640 System.out.println(e); 641 System.out.println(reportErrorMsg); 642 e.printStackTrace(System.err); 643 System.exit(1); 644 } 645 646 System.out.println("Completed."); 647 try 648 { 649 if (con!=null && !con.isClosed()) 650 { 651 con.close(); 652 } 653 } 654 catch (SQLException ex) 655 { 656 System.err.println("SQLError while attempting to close a residual connection"); 657 } 658 } 659 660 661 /** 662 * This method gets called if this applet is envoked as an application. 663 * 664 * @param argv Description of the Parameter 665 */ 666 public static void main(String argv[]) 667 { 668// TableCreator tc = new TableCreator(argv); 669 670 inArgs = argv; 671 672 /* 673 * create an app frame that will start this applet inside it 674 */ 675 WrapperApp app = new WrapperApp("DB Table Creator", new CreateDBTables()); 676 app.pack(); 677 app.setSize(800, 600); 678 679 /* 680 * Put the opening app up 681 */ 682 // app.setVisible(true); 683 // app.setScreenLocation(2,2,0,0); 684 app.dispose(); 685 System.exit(0); 686 } 687} 688