Source Code Cross Referenced for dblook_test.java in  » Database-DBMS » db-derby-10.2 » org » apache » derbyTesting » functionTests » tests » tools » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Database DBMS » db derby 10.2 » org.apache.derbyTesting.functionTests.tests.tools 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:
0003:           Derby - Class org.apache.derbyTesting.functionTests.tests.tools.dblook_test
0004:
0005:           Licensed to the Apache Software Foundation (ASF) under one or more
0006:           contributor license agreements.  See the NOTICE file distributed with
0007:           this work for additional information regarding copyright ownership.
0008:           The ASF licenses this file to You under the Apache License, Version 2.0
0009:           (the "License"); you may not use this file except in compliance with
0010:           the License.  You may obtain a copy of the License at
0011:
0012:              http://www.apache.org/licenses/LICENSE-2.0
0013:
0014:           Unless required by applicable law or agreed to in writing, software
0015:           distributed under the License is distributed on an "AS IS" BASIS,
0016:           WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0017:           See the License for the specific language governing permissions and
0018:           limitations under the License.
0019:
0020:         */
0021:
0022:        package org.apache.derbyTesting.functionTests.tests.tools;
0023:
0024:        import java.sql.DriverManager;
0025:        import java.sql.ResultSet;
0026:        import java.sql.Connection;
0027:        import java.sql.Statement;
0028:        import java.sql.PreparedStatement;
0029:        import java.sql.ResultSetMetaData;
0030:        import java.sql.SQLException;
0031:        import java.sql.SQLWarning;
0032:        import java.sql.Timestamp;
0033:
0034:        import java.io.PrintWriter;
0035:        import java.io.FileOutputStream;
0036:        import java.io.FileNotFoundException;
0037:        import java.io.BufferedReader;
0038:        import java.io.FileReader;
0039:        import java.io.File;
0040:
0041:        import org.apache.derby.tools.dblook;
0042:        import org.apache.derby.tools.ij;
0043:        import org.apache.derby.catalog.DependableFinder;
0044:        import org.apache.derbyTesting.functionTests.util.TestUtil;
0045:
0046:        import java.util.HashMap;
0047:        import java.util.TreeMap;
0048:        import java.util.Set;
0049:        import java.util.Iterator;
0050:        import java.util.ArrayList;
0051:        import java.util.StringTokenizer;
0052:
0053:        public class dblook_test {
0054:
0055:            private static final int SERVER_PORT = 1527;
0056:            private static final int FRONT = -1;
0057:            private static final int REAR = 1;
0058:
0059:            protected static final String dbCreationScript_1 = "dblook_makeDB.sql";
0060:            protected static final String dbCreationScript_2 = "dblook_makeDB_2.sql";
0061:            private static final char TEST_DELIMITER = '#';
0062:
0063:            protected static String testDirectory = "dblook_test";
0064:            protected static final String testDBName = "wombat";
0065:            protected static String separator;
0066:
0067:            private static String dbPath;
0068:            private static int duplicateCounter = 0;
0069:            private static int sysNameCount = 0;
0070:            private static String jdbcProtocol;
0071:
0072:            /* **********************************************
0073:             * main:
0074:             ****/
0075:
0076:            public static void main(String[] args) {
0077:
0078:                separator = System.getProperty("file.separator");
0079:                new dblook_test().doTest();
0080:                System.out.println("\n[ Done. ]\n");
0081:
0082:            }
0083:
0084:            /* **********************************************
0085:             * doTest
0086:             * Run a full test of the dblook utility.
0087:             ****/
0088:
0089:            protected void doTest() {
0090:
0091:                try {
0092:
0093:                    // Test full dblook functionality.
0094:                    System.out
0095:                            .println("\n-= Start dblook Functional Tests. =-");
0096:                    createTestDatabase(dbCreationScript_1);
0097:                    runDBLook(testDBName);
0098:
0099:                    // Test dblook messages.
0100:                    System.out.println("\n-= Start dblook Message Tests =-");
0101:                    createTestDatabase(dbCreationScript_2);
0102:                    runMessageCheckTest(testDBName);
0103:
0104:                } catch (SQLException se) {
0105:
0106:                    System.out.println("FAILED: to complete the test:");
0107:                    se.printStackTrace(System.out);
0108:                    for (se = se.getNextException(); se != null; se = se
0109:                            .getNextException()) {
0110:                        se.printStackTrace(System.out);
0111:                    }
0112:
0113:                } catch (Exception e) {
0114:
0115:                    System.out.println("FAILED: to complete the test:");
0116:                    e.printStackTrace(System.out);
0117:
0118:                }
0119:
0120:            }
0121:
0122:            /* **********************************************
0123:             * createTestDatabase:
0124:             * Using the creation script created as part of
0125:             * the test package, create the database that
0126:             * will be used as the basis for all dblook
0127:             * tests.
0128:             * @param scriptName The name of the sql script
0129:             *  to use for creating the test database.
0130:             * @return The test database has been created
0131:             *  in the current test directory, which is
0132:             *  "./dblook/" (as created by the harness).
0133:             ****/
0134:
0135:            protected void createTestDatabase(String scriptName)
0136:                    throws Exception {
0137:
0138:                // Delete existing database, if it exists.
0139:                try {
0140:                    deleteDB(testDBName);
0141:                } catch (Exception e) {
0142:                    System.out.println("** Warning: failed to delete "
0143:                            + "old test db before creating a new one...");
0144:                }
0145:
0146:                Class.forName("org.apache.derby.jdbc.EmbeddedDriver")
0147:                        .newInstance();
0148:                jdbcProtocol = "jdbc:derby:";
0149:                createDBFromDDL(testDBName, scriptName);
0150:
0151:                // Figure out where our database directory is (abs path).
0152:                String systemhome = System.getProperty("derby.system.home");
0153:                dbPath = systemhome + File.separatorChar;
0154:                return;
0155:
0156:            }
0157:
0158:            /* **********************************************
0159:             * runDBLook:
0160:             * Runs a series of tests using dblook on
0161:             * the received database.
0162:             * @param dbName The name of the database on which to
0163:             *   run the tests.
0164:             * @return A series of tests intended to verify
0165:             *  the full functionality of the dblook utility
0166:             *  has been run.
0167:             ****/
0168:
0169:            private void runDBLook(String dbName) throws Exception {
0170:
0171:                // Close the error stream, so that messages
0172:                // printed to System.err aren't intermixed
0173:                // with our output (otherwise, the order
0174:                // of the System.out vs System.err is
0175:                // arbitrary (because of the way the harness
0176:                // works), and so we will get diffs with
0177:                // the master.
0178:                System.err.close();
0179:
0180:                // First, we dump all system catalogs for
0181:                // the original source database to file.
0182:                dumpSysCatalogs(dbName);
0183:
0184:                // Then, we run dblook on the source database
0185:                // with no limitations (i.e. we generate the
0186:                // DDL for the FULL database).
0187:                lookOne(dbName);
0188:                dumpFileToSysOut("dblook.log");
0189:
0190:                // Now, create new db from the DDL that
0191:                // was generated by dblook.
0192:                String newDBName = dbName + "_new";
0193:                createDBFromDDL(newDBName, dbName + ".sql");
0194:                deleteFile(new File(dbName + ".sql"));
0195:
0196:                // Dump all system catalogs for the database
0197:                // that was created from the DDL generated
0198:                // by dblook.
0199:                dumpSysCatalogs(newDBName);
0200:
0201:                // Delete the new database.
0202:                deleteDB(newDBName);
0203:                deleteFile(new File(newDBName + ".sql"));
0204:
0205:                // Run dblook on the source database
0206:                // with various parameter configurations,
0207:                // to make sure they are all working as
0208:                // planned.
0209:                runAllTests(dbName, newDBName);
0210:
0211:            }
0212:
0213:            /* **********************************************
0214:             * runAllTests:
0215:             * Makes the call to execute each of the desired
0216:             * tests.
0217:             * @param dbName The name of the database on which to
0218:             *   run the tests.
0219:             * @param newDBName The name of the database to be
0220:             *  created from the DDL that is generated (by
0221:             *  dblook) for the source database.
0222:             ****/
0223:
0224:            protected void runAllTests(String dbName, String newDBName)
0225:                    throws Exception {
0226:
0227:                runTest(2, dbName, newDBName);
0228:
0229:                // Test 3 is run as part of derbynet suite;
0230:                // see derbynet/dblook_test_net.java.
0231:
0232:                runTest(4, dbName, newDBName);
0233:                runTest(5, dbName, newDBName);
0234:                runTest(7, dbName, newDBName);
0235:                runTest(6, dbName, newDBName);
0236:                return;
0237:
0238:            }
0239:
0240:            /* **********************************************
0241:             * runTest:
0242:             * Runs dblook on the source database with a
0243:             * specific set of parameters, then uses the
0244:             * resultant DDL to create a new database, and
0245:             * dumps the system catalogs for that database
0246:             * to file.  Finally, the new database is deleted
0247:             * in preparation for subsequent calls to this
0248:             * method.
0249:             * @param whichTest An indication of which test to run;
0250:             *  each test number has a different set of
0251:             *  parameters.
0252:             * @param dbName The name of the source database.
0253:             * @param newDBName The name of the database to be
0254:             *  created from the DDL that is generated (by
0255:             *  dblook) for the source database.
0256:             * @return dblook has been executed using the
0257:             *  parameters associated with the given test,
0258:             *  and that DDL has been written to a ".sql"
0259:             *  file named after the source database;
0260:             *  a new database has been created from the
0261:             *  ".sql" generated by dblook; the system
0262:             *  catalogs for that new database have been
0263:             *  dumped to output; and the new database has
0264:             *  been deleted.
0265:             ****/
0266:
0267:            protected void runTest(int whichTest, String dbName,
0268:                    String newDBName) {
0269:
0270:                try {
0271:
0272:                    switch (whichTest) {
0273:                    case 2:
0274:                        lookTwo(dbName);
0275:                        break;
0276:                    case 3:
0277:                        lookThree(dbName);
0278:                        break;
0279:                    case 4:
0280:                        lookFour(dbName);
0281:                        break;
0282:                    case 5:
0283:                        lookFive(dbName);
0284:                        break;
0285:                    case 6:
0286:                        lookSix(dbName);
0287:                        break;
0288:                    case 7:
0289:                        lookSeven(dbName);
0290:                        break;
0291:                    default:
0292:                        break;
0293:                    }
0294:
0295:                    dumpFileToSysOut("dblook.log");
0296:                    createDBFromDDL(newDBName, dbName + ".sql");
0297:                    dumpSysCatalogs(newDBName);
0298:                    deleteDB(newDBName);
0299:                    deleteFile(new File(dbName + ".sql"));
0300:
0301:                } catch (SQLException e) {
0302:
0303:                    System.out.println("FAILED: Test # : " + whichTest);
0304:                    e.printStackTrace(System.out);
0305:                    for (e = e.getNextException(); e != null; e = e
0306:                            .getNextException()) {
0307:                        e.printStackTrace(System.out);
0308:                    }
0309:
0310:                } catch (Exception e) {
0311:
0312:                    System.out.println("FAILED: Test # : " + whichTest);
0313:                    e.printStackTrace(System.out);
0314:
0315:                }
0316:
0317:                return;
0318:
0319:            }
0320:
0321:            /* **********************************************
0322:             * lookOne:
0323:             * Use dblook to generate FULL DDL for a given
0324:             * database.
0325:             * @param dbName The name of the source database (i.e.
0326:             *  the database for which the DDL is generated).
0327:             * @return The full DDL for the source database
0328:             *  has been generated and written to a file
0329:             *  called <dbName + ".sql">.
0330:             ****/
0331:
0332:            private void lookOne(String dbName) throws Exception {
0333:
0334:                printAsHeader("\nDumping full schema for '" + dbName
0335:                        + "'\nto file '" + dbName + ".sql':\n");
0336:
0337:                String[] args = new String[] { "-o", dbName + ".sql", "-td", "" };
0338:
0339:                go(dbName, args);
0340:                return;
0341:
0342:            }
0343:
0344:            /* **********************************************
0345:             * lookTwo:
0346:             * Use dblook to generate DDL for all objects 
0347:             * in the source database with schema 'BAR',
0348:             * excluding views:
0349:             *  -z bar -noview
0350:             * @param dbName The name of the source database (i.e.
0351:             *  the database for which the DDL is generated).
0352:             * @return The appropriate DDL has been generated
0353:             *  and written to a file called <dbName + ".sql">.
0354:             ****/
0355:
0356:            private void lookTwo(String dbName) throws Exception {
0357:
0358:                printAsHeader("\nDumping DDL for all objects "
0359:                        + "with schema\n'BAR', excluding views:\n");
0360:
0361:                String[] args = new String[] { "-o", dbName + ".sql", "-td",
0362:                        "", "-z", "bar", "-noview" };
0363:
0364:                go(dbName, args);
0365:                return;
0366:
0367:            }
0368:
0369:            /* **********************************************
0370:             * lookThree:
0371:             * Use dblook to generate DDL for all objects
0372:             * in the source database, using Network
0373:             * Server.
0374:             * @param dbName The name of the source database (i.e.
0375:             *  the database for which the DDL is generated).
0376:             * @return The appropriate DDL has been generated
0377:             *  and written to a file called <dbName + ".sql">.
0378:             ****/
0379:
0380:            private void lookThree(String dbName) throws Exception {
0381:
0382:                printAsHeader("\nDumping DDL for all objects, "
0383:                        + "using\nNetwork Server:\n");
0384:                String hostName = TestUtil.getHostName();
0385:                jdbcProtocol = TestUtil.getJdbcUrlPrefix(hostName, SERVER_PORT);
0386:
0387:                String sourceDBUrl;
0388:                if (TestUtil.isJCCFramework())
0389:                    sourceDBUrl = jdbcProtocol + "\"" + dbPath + separator
0390:                            + dbName + "\":user=someusr;password=somepwd;";
0391:                else
0392:                    sourceDBUrl = jdbcProtocol + dbPath + separator + dbName
0393:                            + ";user=someusr;password=somepwd";
0394:
0395:                // Make sure we're not connected to the database
0396:                // (we connected to it in embedded mode when we
0397:                // created it, so we have to shut it down).
0398:                try {
0399:                    DriverManager.getConnection("jdbc:derby:" + dbName
0400:                            + ";shutdown=true");
0401:                } catch (SQLException e) {
0402:                }
0403:
0404:                // Run the test.
0405:                try {
0406:
0407:                    new dblook(new String[] { "-d", sourceDBUrl, "-o",
0408:                            dbName + ".sql", "-td", "" });
0409:
0410:                } catch (Exception e) {
0411:                    System.out.println("FAILED: ");
0412:                    e.printStackTrace(System.out);
0413:                }
0414:
0415:                return;
0416:
0417:            }
0418:
0419:            /* **********************************************
0420:             * lookFour:
0421:             * Use dblook to generate DDL for all objects 
0422:             * in the source database with schema 'BAR'
0423:             * that are related to tables 'T3', 'tWithKeys',
0424:             * and 'MULTI WORD NAME'.
0425:             *  -z bar -t t3 "\"tWithKeys\"" "Multi word name"
0426:             * @param dbName The name of the source database (i.e.
0427:             *  the database for which the DDL is generated).
0428:             * @return The appropriate DDL has been generated
0429:             *  and written to a file called <dbName + ".sql">.
0430:             ****/
0431:
0432:            private void lookFour(String dbName) throws Exception {
0433:
0434:                printAsHeader("\nDumping DDL for all objects "
0435:                        + "with schema 'BAR'\nthat are related to tables "
0436:                        + "'T3', 'tWithKeys',\nand 'MULTI WORD NAME':\n");
0437:
0438:                String[] args = new String[] { "-o", dbName + ".sql", "-td",
0439:                        "", "-z", "BAR", "-t", "t3", "\"tWithKeys\"",
0440:                        "Multi word name" };
0441:
0442:                go(dbName, args);
0443:                return;
0444:
0445:            }
0446:
0447:            /* **********************************************
0448:             * lookFive:
0449:             * Use dblook to generate DDL for all objects 
0450:             * in the source database (with any schema)
0451:             * that are related to table 'T1' and 'TWITHKEYS'
0452:             * (with no matches existing for the latter).
0453:             * 	-t t1 "tWithKeys"
0454:             * @param dbName The name of the source database (i.e.
0455:             *  the database for which the DDL is generated).
0456:             * @return The appropriate DDL has been generated
0457:             *  and written to a file called <dbName + ".sql">.
0458:             ****/
0459:
0460:            private void lookFive(String dbName) throws Exception {
0461:
0462:                printAsHeader("\nDumping DDL for all objects "
0463:                        + "related to 'T1'\nand 'TWITHKEYS':\n");
0464:
0465:                String[] args = new String[] { "-o", dbName + ".sql", "-td",
0466:                        "", "-t", "t1", "tWithKeys" };
0467:
0468:                go(dbName, args);
0469:                return;
0470:
0471:            }
0472:
0473:            /* **********************************************
0474:             * lookSix:
0475:             * Call dblook with an invalid url, to make
0476:             * sure that errors are printed to log.
0477:             *   -d <dbName> // missing protocol.
0478:             * @param dbName The name of the source database (i.e.
0479:             *  the database for which the DDL is generated).
0480:             * @return The appropriate DDL has been generated
0481:             *  and written to a file called <dbName + ".sql">.
0482:             ****/
0483:
0484:            private void lookSix(String dbName) throws Exception {
0485:
0486:                printAsHeader("\nDumping DDL w/ invalid url, and "
0487:                        + "writing\nerror to the log:\n");
0488:
0489:                // Url is intentionally incorrect; it will cause an error.
0490:                new dblook(new String[] { "-o", dbName + ".sql", "-d", dbName });
0491:
0492:            }
0493:
0494:            /* **********************************************
0495:             * lookSeven:
0496:             * Use dblook to generate DDL for all objects 
0497:             * in the source database with schema '"Quoted"Schema"'.
0498:             *  -z \"\"Quoted\"Schema\"\"
0499:             * @param dbName The name of the source database (i.e.
0500:             *  the database for which the DDL is generated).
0501:             * @return The appropriate DDL has been generated
0502:             *  and written to a file called <dbName + ".sql">.
0503:             ****/
0504:
0505:            private void lookSeven(String dbName) throws Exception {
0506:
0507:                printAsHeader("\nDumping DDL for all objects "
0508:                        + "with schema\n'\"Quoted\"Schema\"':\n");
0509:
0510:                String[] args = new String[] { "-o", dbName + ".sql", "-td",
0511:                        "", "-z", "\"\"Quoted\"Schema\"\"" };
0512:
0513:                go(dbName, args);
0514:                return;
0515:
0516:            }
0517:
0518:            /* **********************************************
0519:             * go:
0520:             * Makes the call to execute the dblook command
0521:             * using the received arguments.
0522:             * @param dbName The name of the source database (i.e.
0523:             *  the database for which the DDL is generated).
0524:             * @args The list of arguments with which to execute
0525:             *  the dblook command.
0526:             ****/
0527:
0528:            private void go(String dbName, String[] args) {
0529:
0530:                jdbcProtocol = "jdbc:derby:";
0531:                String sourceDBUrl = jdbcProtocol + dbPath + separator + dbName;
0532:
0533:                String[] fullArgs = new String[args.length + 2];
0534:                fullArgs[0] = "-d";
0535:                fullArgs[1] = sourceDBUrl;
0536:                for (int i = 2; i < fullArgs.length; i++)
0537:                    fullArgs[i] = args[i - 2];
0538:
0539:                try {
0540:                    new dblook(fullArgs);
0541:                } catch (Exception e) {
0542:                    System.out.println("FAILED: to run dblook: ");
0543:                    e.printStackTrace(System.out);
0544:                }
0545:
0546:            }
0547:
0548:            /* **********************************************
0549:             * runMessageCheckTest
0550:             * Run dblook and verify that all of the dblook
0551:             * messages are correctly displayed.
0552:             * @param dbName The name of the source database (i.e.
0553:             *  the database for which the DDL is generated).
0554:             * @return The DDL for a simple database, plus all
0555:             *  dblook messages, have been generated and written
0556:             *  to System.out.
0557:             ****/
0558:            private void runMessageCheckTest(String dbName) throws Exception {
0559:
0560:                // #1: First, run DB look standard to check for
0561:                // all of the "header" messages that are printed
0562:                // out along with DDL.
0563:                System.out.println("\n************\n" + "Msg Test 1\n"
0564:                        + "************\n");
0565:                lookOne(dbName);
0566:                dumpFileToSysOut(dbName + ".sql");
0567:                dumpFileToSysOut("dblook.log");
0568:
0569:                // Now, we have to run some additional dblook commands
0570:                // to get the "non-standard" messages.
0571:
0572:                // #2: Specify a target table and target schema, to
0573:                // make sure they are echoed correctly.  Also, specify
0574:                // an output file to make sure the file creation header
0575:                // is printed in the file.
0576:                System.out.println("\n************\n" + "Msg Test 2\n"
0577:                        + "************\n");
0578:                go(dbName, new String[] { "-t", "t1", "-z", "bar", "-o",
0579:                        dbName + ".sql" });
0580:                dumpFileToSysOut(dbName + ".sql");
0581:                dumpFileToSysOut("dblook.log");
0582:
0583:                // #3: Run without specifying a database, to make
0584:                // sure the usage message is printed to System.out
0585:                System.out.println("\n************\n" + "Msg Test 3\n"
0586:                        + "************\n");
0587:                try {
0588:                    new dblook(new String[] { "-verbose" });
0589:                } catch (Exception e) {
0590:                    System.out.println("FAILED: to run dblook: ");
0591:                    e.printStackTrace(System.out);
0592:                }
0593:
0594:                // #4: Just to confirm, try once with a statement
0595:                // delimiter, to make sure it's actually working
0596:                // correctly (this isn't a "message" per se, but
0597:                // still, it's worth verifying).
0598:                System.out.println("\n************\n" + "Msg Test 4\n"
0599:                        + "************\n");
0600:                go(dbName, new String[] { "-td", " " + TEST_DELIMITER });
0601:
0602:                // #5: Intentionally create an error while loading
0603:                // a jar file, to make sure the resultant message is
0604:                // printed correctly.
0605:                System.out.println("\n************\n" + "Msg Test 5\n"
0606:                        + "************\n");
0607:
0608:                // We'll cause the error by going in and deleting
0609:                // the jar file from the test database.  First,
0610:                // get the jar path.
0611:                String jarPath = (new File(dbPath + separator + dbName))
0612:                        .getAbsolutePath();
0613:
0614:                // Have to shut db down before we can mess with it.
0615:                try {
0616:                    Connection conn = DriverManager.getConnection("jdbc:derby:"
0617:                            + jarPath + ";shutdown=true");
0618:                    conn.close();
0619:                } catch (SQLException se) {
0620:                    // shutdown exception.
0621:                }
0622:
0623:                jarPath = jarPath + separator + "jar";
0624:                deleteFile(new File(jarPath));
0625:
0626:                // Now that we've deleted the jar file, run dblook
0627:                // and check the error.
0628:                go(dbName, new String[] { "-verbose", "-o", dbName + ".sql" });
0629:                dumpFileToSysOut("dblook.log");
0630:
0631:                // Clean up.
0632:                try {
0633:                    deleteFile(new File(dbName + ".sql"));
0634:                } catch (Exception e) {
0635:                    // not too big of a deal if we fail; just ignore...
0636:                }
0637:
0638:            }
0639:
0640:            /* **********************************************
0641:             * dumpSysCatalogs:
0642:             * Takes a database name and dumps ALL of the
0643:             * system catalogs for that database, with the
0644:             * exception of SYSSTATISTICS.  This allows us
0645:             * to look at the full contents of a database's
0646:             * schema (without using dblook, of course)
0647:             * so that we can see if the databases created
0648:             * from the DDL generated by dblook have been
0649:             * built correctly--if they have all of the
0650:             * correct system catalog information, then
0651:             * the databases themselves must be correct.
0652:             * @param dbName The name of the database for which
0653:             *  we are dumping the system catalogs.
0654:             * @return All of the system catalogs for
0655:             *  the received database have been dumped
0656:             *  to output.
0657:             ****/
0658:
0659:            private void dumpSysCatalogs(String dbName) throws Exception {
0660:
0661:                System.out.println("\nDumping system tables for '" + dbName
0662:                        + "'\n");
0663:
0664:                writeOut("\n----------------=================---------------");
0665:                writeOut("System Tables for: " + dbName);
0666:                writeOut("----------------=================---------------\n");
0667:
0668:                // Connect to the database.
0669:                Connection conn = DriverManager.getConnection("jdbc:derby:"
0670:                        + dbName);
0671:                conn.setAutoCommit(false);
0672:                Statement stmt = conn.createStatement();
0673:
0674:                // Load any id-to-name mappings that will be useful
0675:                // when dumping the catalogs.
0676:                HashMap idToNameMap = loadIdMappings(stmt, conn);
0677:
0678:                // Go through and dump all system catalog information,
0679:                // filtering out database-dependent id's so that they
0680:                // won't cause diffs.
0681:
0682:                writeOut("\n========== SYSALIASES ==========\n");
0683:                ResultSet rs = stmt
0684:                        .executeQuery("select schemaid, sys.sysaliases.* from sys.sysaliases");
0685:                dumpResultSet(rs, idToNameMap, null);
0686:
0687:                writeOut("\n========== SYSCHECKS ==========\n");
0688:                rs = stmt.executeQuery("select c.schemaid, ck.* from "
0689:                        + "sys.syschecks ck, sys.sysconstraints c where "
0690:                        + "ck.constraintid = c.constraintid");
0691:                dumpResultSet(rs, idToNameMap, null);
0692:
0693:                writeOut("\n========== SYSCOLUMNS ==========\n");
0694:                writeOut("--- Columns for Tables ---");
0695:                rs = stmt
0696:                        .executeQuery("select t.schemaid, c.* from "
0697:                                + "sys.syscolumns c, sys.systables t where c.referenceid "
0698:                                + "= t.tableid");
0699:                dumpResultSet(rs, idToNameMap, null);
0700:                writeOut("\n--- Columns for Statements ---");
0701:                rs = stmt
0702:                        .executeQuery("select s.schemaid, c.* from "
0703:                                + "sys.syscolumns c, sys.sysstatements s where c.referenceid "
0704:                                + "= s.stmtid");
0705:                dumpResultSet(rs, idToNameMap, null);
0706:
0707:                writeOut("\n========== SYSCONGLOMERATES ==========\n");
0708:                rs = stmt
0709:                        .executeQuery("select schemaid, sys.sysconglomerates.* "
0710:                                + "from sys.sysconglomerates");
0711:                dumpResultSet(rs, idToNameMap, null);
0712:
0713:                writeOut("\n========== SYSCONSTRAINTS ==========\n");
0714:                rs = stmt.executeQuery("select schemaid, sys.sysconstraints.* "
0715:                        + "from sys.sysconstraints");
0716:                dumpResultSet(rs, idToNameMap, null);
0717:
0718:                writeOut("\n========== SYSDEPENDS ==========\n");
0719:                rs = stmt
0720:                        .executeQuery("select dependentid, sys.sysdepends.* from sys.sysdepends");
0721:                dumpResultSet(rs, idToNameMap, conn);
0722:
0723:                writeOut("\n========== SYSFILES ==========\n");
0724:                rs = stmt
0725:                        .executeQuery("select schemaid, sys.sysfiles.* from sys.sysfiles");
0726:                dumpResultSet(rs, idToNameMap, null);
0727:
0728:                writeOut("\n========== SYSFOREIGNKEYS ==========\n");
0729:                rs = stmt.executeQuery("select c.schemaid, fk.* from "
0730:                        + "sys.sysforeignkeys fk, sys.sysconstraints c where "
0731:                        + "fk.constraintid = c.constraintid");
0732:                dumpResultSet(rs, idToNameMap, null);
0733:
0734:                writeOut("\n========== SYSKEYS ==========\n");
0735:                rs = stmt.executeQuery("select c.schemaid, k.* from "
0736:                        + "sys.syskeys k, sys.sysconstraints c where "
0737:                        + "k.constraintid = c.constraintid");
0738:                dumpResultSet(rs, idToNameMap, null);
0739:
0740:                writeOut("\n========== SYSSCHEMAS ==========\n");
0741:                rs = stmt
0742:                        .executeQuery("select schemaid, sys.sysschemas.* from sys.sysschemas");
0743:                dumpResultSet(rs, idToNameMap, null);
0744:
0745:                writeOut("\n========== SYSSTATEMENTS ==========\n");
0746:                rs = stmt
0747:                        .executeQuery("select schemaid, sys.sysstatements.* from sys.sysstatements");
0748:                dumpResultSet(rs, idToNameMap, null);
0749:
0750:                writeOut("\n========== SYSTABLES ==========\n");
0751:                rs = stmt
0752:                        .executeQuery("select schemaid, sys.systables.* from sys.systables");
0753:                dumpResultSet(rs, idToNameMap, null);
0754:
0755:                writeOut("\n========== SYSTRIGGERS ==========\n");
0756:                rs = stmt
0757:                        .executeQuery("select schemaid, sys.systriggers.* from sys.systriggers");
0758:                dumpResultSet(rs, idToNameMap, null);
0759:
0760:                writeOut("\n========== SYSVIEWS ==========\n");
0761:                rs = stmt
0762:                        .executeQuery("select compilationschemaid, sys.sysviews.* from sys.sysviews");
0763:                dumpResultSet(rs, idToNameMap, null);
0764:
0765:                stmt.close();
0766:                rs.close();
0767:                conn.commit();
0768:                conn.close();
0769:                return;
0770:
0771:            }
0772:
0773:            /* **********************************************
0774:             * isIgnorableSchema:
0775:             * Returns true if the the schema is a "system" schema, vs. a user 
0776:             * schema.  
0777:             * @param schemaName name of schema to check.
0778:             ****/
0779:            private boolean isIgnorableSchema(String schemaName) {
0780:
0781:                boolean ret = false;
0782:
0783:                for (int i = ignorableSchemaNames.length - 1; i >= 0;) {
0784:                    if ((ret = ignorableSchemaNames[i--]
0785:                            .equalsIgnoreCase(schemaName)))
0786:                        break;
0787:                }
0788:
0789:                return (ret);
0790:            }
0791:
0792:            private static final String[] ignorableSchemaNames = { "SYSIBM",
0793:                    "SYS", "SYSVISUAL", "SYSCAT", "SYSFUN", "SYSPROC",
0794:                    "SYSSTAT", "NULLID", "SYSCS_ADMIN", "SYSCS_DIAG",
0795:                    "SYSCS_UTIL", "SQLJ" };
0796:
0797:            /* **********************************************
0798:             * dumpResultSet:
0799:             * Iterates through the received result set and
0800:             * dumps ALL columns in ALL rows of that result
0801:             * set to output.  Since no order is guaranteed
0802:             * in the received result set, we have to generate
0803:             * unique "ids" for each row in the result, and
0804:             * then use those ids to determine what order the
0805:             * rows will be output.  Failure to do so will
0806:             * lead to diffs in the test for rows that occur
0807:             * out of order.  The unique id's must NOT
0808:             * depend on system-generated id's, as the
0809:             * latter will vary for every run of the test,
0810:             * and thus will lead to different orderings
0811:             * every time (which we don't want).
0812:             *
0813:             * @param rs The result set that is being dumped.
0814:             * @param idToNameMap Mapping of various ids to
0815:             *  object names; used in forming unique ids.
0816:             * @param conn Connection from which the result set
0817:             *  originated.
0818:             ****/
0819:
0820:            private void dumpResultSet(ResultSet rs, HashMap idToNameMap,
0821:                    Connection conn) throws Exception {
0822:
0823:                // We need to form unique names for the rows of the
0824:                // result set so that we can preserve the order of
0825:                // the output and avoid diffs with a master.  This is
0826:                // because a "select *" doesn't order rows--and even
0827:                // though the schema for two databases might be the
0828:                // same (i.e. the system tables contain all of the same
0829:                // information) there's nothing to say the various rows in
0830:                // the respective system tables will be the same (they
0831:                // usually are NOT).  While system id's automatically
0832:                // give us uniqueness, we can NOT order on them because
0833:                // they vary from database to database; so, we need
0834:                // to use something constant across the databases,
0835:                // which is why we use object names.
0836:                StringBuffer uniqueName = new StringBuffer();
0837:
0838:                TreeMap orderedRows = new TreeMap();
0839:                ArrayList rowValues = new ArrayList();
0840:                ArrayList duplicateRowIds = new ArrayList();
0841:
0842:                ResultSetMetaData rsmd = rs.getMetaData();
0843:                int cols = rsmd.getColumnCount();
0844:                while (rs.next()) {
0845:
0846:                    for (int i = 1; i <= cols; i++) {
0847:
0848:                        String colName = rsmd.getColumnName(i);
0849:                        String value = rs.getString(i);
0850:                        String mappedName = (String) idToNameMap.get(value);
0851:
0852:                        if ((colName.indexOf("SCHEMAID") != -1)
0853:                                && (mappedName != null)
0854:                                && ((mappedName.indexOf("SYS") != -1) || (isIgnorableSchema(mappedName)))) {
0855:                            // then this row of the result set is for a system
0856:                            // object, which will always be the same for the
0857:                            // source and new database, so don't bother dumping
0858:                            // them to the output file (makes the test less
0859:                            // like to require updates when changes to database
0860:                            // metadata for system objects are checked in).
0861:                            rowValues = null;
0862:                            break;
0863:                        } else if (colName.equals("JAVACLASSNAME")
0864:                                && (value != null)
0865:                                && (value.indexOf("org.apache.derby") != -1)
0866:                                && (value.indexOf(".util.") == -1)) {
0867:                            // this is a -- hack -- to see if the alias is a
0868:                            // a system alias, needed because aliases
0869:                            // (other than stored procedures) do not have
0870:                            // an associated schema).
0871:                            rowValues = null;
0872:                            break;
0873:                        }
0874:
0875:                        if (i == 1)
0876:                            // 1st column is just for figuring out whether
0877:                            // to dump this row; no need to actually include
0878:                            // it in the results.
0879:                            continue;
0880:
0881:                        String uniquePiece = dumpColumnData(colName, value,
0882:                                mappedName, rowValues);
0883:
0884:                        if (colName.equals("DEPENDENTID")) {
0885:                            // Special case: rows in the "DEPENDS" table
0886:                            // don't have unique ids or names; we have to
0887:                            // build one by extracting information indirectly.
0888:                            String hiddenInfo = getDependsData(rs, conn,
0889:                                    idToNameMap);
0890:                            if (hiddenInfo.indexOf("SYS_OBJECT") != -1) {
0891:                                // this info is for a system object, so
0892:                                // ignore it.
0893:                                rowValues = null;
0894:                                break;
0895:                            }
0896:                            uniqueName.append(hiddenInfo);
0897:                            // Include the hidden data as part of the
0898:                            // output.
0899:                            rowValues.add(hiddenInfo);
0900:                        }
0901:
0902:                        if (uniquePiece != null)
0903:                            uniqueName.append(uniquePiece);
0904:
0905:                        if (colName.equals("STMTNAME")
0906:                                && (value.indexOf("TRIGGERACTN") != -1))
0907:                            // Special case: can't use statement name, because
0908:                            // the entire statement may be automatically generated
0909:                            // in each database (to back a trigger), so the name
0910:                            // in which case the generated name will be different
0911:                            // every time; but filtering out the name means
0912:                            // we have no other guaranteed unique 'id' for
0913:                            // ordering.  So, just take "text" field, and
0914:                            // design test db so that no two triggers have the
0915:                            // same text value.
0916:                            uniqueName.append(rs.getString(6));
0917:
0918:                    }
0919:
0920:                    if (rowValues != null) {
0921:
0922:                        if (duplicateRowIds.contains(uniqueName.toString()))
0923:                            // then we've already encountered this row id before;
0924:                            // to preserve ordering, use the entire row as an
0925:                            // id.
0926:                            handleDuplicateRow(rowValues, null, orderedRows);
0927:                        else {
0928:                            ArrayList oldRow = (ArrayList) (orderedRows.put(
0929:                                    uniqueName.toString(), rowValues));
0930:                            if (oldRow != null) {
0931:                                // Duplicate row id.
0932:                                duplicateRowIds.add(uniqueName.toString());
0933:                                // Delete the row that has the duplicate row id.
0934:                                orderedRows.remove(uniqueName.toString());
0935:                                handleDuplicateRow(rowValues, oldRow,
0936:                                        orderedRows);
0937:                            }
0938:                        }
0939:                    }
0940:
0941:                    uniqueName = new StringBuffer();
0942:                    rowValues = new ArrayList();
0943:
0944:                }
0945:
0946:                // Now, print out all of the data in this result set
0947:                // using the order of the unique names that we created.
0948:                Set objectNames = orderedRows.keySet();
0949:                for (Iterator itr = objectNames.iterator(); itr.hasNext();) {
0950:
0951:                    String row = (String) itr.next();
0952:                    ArrayList colData = (ArrayList) orderedRows.get(row);
0953:                    for (int i = 0; i < colData.size(); i++)
0954:                        writeOut((String) colData.get(i));
0955:                    writeOut("----");
0956:
0957:                }
0958:
0959:                orderedRows = null;
0960:                rs.close();
0961:
0962:            }
0963:
0964:            /* **********************************************
0965:             * dumpColumnData:
0966:             * Stores the value for a specific column of
0967:             * some result set.  If the value needs to
0968:             * be filtered (to remove system-generated ids
0969:             * that would otherwise cause diffs with the
0970:             * master), that filtering is done here.
0971:             * @param colName Name of the column whose value we're
0972:             *  writing.
0973:             * @param value Value that we're writing.
0974:             * @param mappedName: Name corresponding to the value,
0975:             *  for cases where the value is actually an
0976:             *  object id (then we want to write the name
0977:             *  instead).
0978:             * rowValues a list of column values for the
0979:             *  current row of the result set.
0980:             * @return The (possibly filtered) value of the
0981:             *  received column has been added to the
0982:             *  "rowVals" array list, and the corresponding
0983:             *  piece of the row's unique name has been
0984:             *  returned, if one exists.
0985:             ****/
0986:
0987:            private String dumpColumnData(String colName, String value,
0988:                    String mappedName, ArrayList rowVals) {
0989:
0990:                if (mappedName == null) {
0991:                    // probably not an id.
0992:                    if (colName.equals("CONGLOMERATENUMBER")
0993:                            || colName.equals("GENERATIONID"))
0994:                        // special case: these numbers aren't ids per
0995:                        // se, but they are still generated by the system,
0996:                        // and will cause diffs with the master; so, ignore
0997:                        // them.
0998:                        rowVals.add("<systemnumber>");
0999:                    else if (colName.equals("AUTOINCREMENTVALUE"))
1000:                        // special case: new database won't have any data,
1001:                        // old will, so unless we filter this out, we'll
1002:                        // get a diff.
1003:                        rowVals.add("<autoincval>");
1004:                    else if (colName.equals("VALID"))
1005:                        // special case: ignore whether or not stored
1006:                        // statements are valid (have been compiled)
1007:                        // since it depends on history of database,
1008:                        // which we can't duplicate.
1009:                        rowVals.add("<validityflag>");
1010:                    else if (value != null) {
1011:                        if (looksLikeSysGenName(value)) {
1012:                            if (columnHoldsObjectName(colName))
1013:                                rowVals.add("<systemname>");
1014:                            else {
1015:                                // looks like a sys gen name, but's actually a VALUE.
1016:                                rowVals.add(value);
1017:                                return value;
1018:                            }
1019:                        } else if (looksLikeSysGenId(value))
1020:                            rowVals.add("<systemid>");
1021:                        else {
1022:                            rowVals.add(value);
1023:                            if (columnHoldsObjectName(colName))
1024:                                // if it's a name, we need it as part of
1025:                                // our unique id.
1026:                                return value;
1027:                        }
1028:                    } else
1029:                        // null value.
1030:                        rowVals.add(value);
1031:                } else {
1032:                    // it's an id, so write the corresponding name.
1033:                    if (!isSystemGenerated(mappedName)) {
1034:                        // Not an id-as-name, so use it as part of our unique id.
1035:                        rowVals.add(mappedName);
1036:                        return mappedName;
1037:                    } else
1038:                        rowVals.add("<systemname>");
1039:                }
1040:
1041:                // If we get here, we do NOT want the received value
1042:                // to be treated as part of this row's unique name.
1043:                return null;
1044:
1045:            }
1046:
1047:            /* **********************************************
1048:             * handleDuplicateRow:
1049:             * If we get here, then despite our efforts (while
1050:             * dumping the system catalogs for a database), we
1051:             * still have a duplicate row id.  So, as a last
1052:             * resort we just use the ENTIRE row as a 'row id'.
1053:             * In the rare-but-possible case that the entire
1054:             * row is a duplicate (as can happen with the
1055:             * SYSDEPENDS table), then we tag a simple number
1056:             * onto the latest row's id, so that the row will
1057:             * still show up multiple times--and since the rows
1058:             * are identical, it doesn't matter which comes
1059:             * 'first'.
1060:             * @param newRow The most recently-fetched row from
1061:             *  the database system catalogs.
1062:             * @param oldRow The row that was replaced when the
1063:             *  newRow was inserted (because they had the
1064:             *  same row id), or "null" if we were already
1065:             *  here once for this row id, and so just want
1066:             *  insert a new row.
1067:             * @param orderedRows The ordered set of rows, into
1068:             *  which oldRow and newRow need to be inserted.
1069:             * @return oldRow and newRow have been inserted
1070:             *  into orderedRows, and each has a (truly)
1071:             *  unique id with it.
1072:             ****/
1073:
1074:            private void handleDuplicateRow(ArrayList newRow, ArrayList oldRow,
1075:                    TreeMap orderedRows) {
1076:
1077:                // Add the received rows (old and new) with
1078:                // unique row ids.
1079:
1080:                StringBuffer newRowId = new StringBuffer();
1081:                for (int i = 0; i < newRow.size(); i++)
1082:                    newRowId.append((String) newRow.get(i));
1083:
1084:                Object obj = (ArrayList) (orderedRows.put(newRowId.toString(),
1085:                        newRow));
1086:                if (obj != null)
1087:                    // entire row is a duplicate.
1088:                    orderedRows.put(newRowId.toString() + duplicateCounter++,
1089:                            newRow);
1090:
1091:                if (oldRow != null) {
1092:
1093:                    StringBuffer oldRowId = new StringBuffer();
1094:                    for (int i = 0; i < oldRow.size(); i++)
1095:                        oldRowId.append((String) oldRow.get(i));
1096:
1097:                    obj = (ArrayList) (orderedRows.put(oldRowId.toString(),
1098:                            oldRow));
1099:                    if (obj != null)
1100:                        // entire row is a duplicate.
1101:                        orderedRows.put(oldRowId.toString()
1102:                                + duplicateCounter++, oldRow);
1103:                }
1104:
1105:                return;
1106:
1107:            }
1108:
1109:            /* **********************************************
1110:             * createDBFromDDL:
1111:             * Read from the given script and use it to create
1112:             * a new database of the given name.
1113:             * @param newDBName Name of the database to be created.
1114:             * @param scriptName Name of the script containing the
1115:             *  DDL from which the new database will be created.
1116:             * @return New database has been created from
1117:             *   the script; any commands in the script that
1118:             *   failed to execute have been echoed to output.
1119:             ****/
1120:
1121:            private void createDBFromDDL(String newDBName, String scriptName)
1122:                    throws Exception {
1123:
1124:                System.out.println("\n\nCreating database '" + newDBName
1125:                        + "' from ddl script '" + scriptName + "'");
1126:
1127:                Connection conn = DriverManager.getConnection("jdbc:derby:"
1128:                        + newDBName + ";create=true");
1129:
1130:                Statement stmt = conn.createStatement();
1131:                BufferedReader ddlScript = new BufferedReader(new FileReader(
1132:                        scriptName));
1133:
1134:                for (String sqlCmd = ddlScript.readLine(); sqlCmd != null; sqlCmd = ddlScript
1135:                        .readLine()) {
1136:
1137:                    if (sqlCmd.indexOf("--") == 0)
1138:                        // then this is a script comment; ignore it;
1139:                        continue;
1140:                    else if (sqlCmd.trim().length() == 0)
1141:                        // blank line; ignore it.
1142:                        continue;
1143:
1144:                    // Execute the command.
1145:                    if ((sqlCmd.charAt(sqlCmd.length() - 1) == TEST_DELIMITER)
1146:                            || (sqlCmd.charAt(sqlCmd.length() - 1) == ';'))
1147:                        // strip off the delimiter.
1148:                        sqlCmd = sqlCmd.substring(0, sqlCmd.length() - 1);
1149:
1150:                    try {
1151:                        stmt.execute(sqlCmd);
1152:                    } catch (Exception e) {
1153:                        System.out.println("FAILED: to execute cmd "
1154:                                + "from DDL script:\n" + sqlCmd + "\n");
1155:                        System.out.println(e.getMessage());
1156:                    }
1157:
1158:                }
1159:
1160:                // Cleanup.
1161:                ddlScript.close();
1162:                stmt.close();
1163:                conn.close();
1164:
1165:                return;
1166:
1167:            }
1168:
1169:            /* **********************************************
1170:             * writeOut:
1171:             * Write the received string to some output.
1172:             * @param str String to write.
1173:             ****/
1174:
1175:            private static void writeOut(String str) {
1176:
1177:                System.out.println(str);
1178:                return;
1179:
1180:            }
1181:
1182:            /* **********************************************
1183:             * loadIdMappings:
1184:             * Load mappings of object ids to object names
1185:             * for purposes of having meaningful output
1186:             * and for creating unique ids on the rows of
1187:             * the system catalogs.
1188:             * @param stmt Statement on a connection to the
1189:             *  database being examined.
1190:             * @param conn Connection to the database being
1191:             *   examined.
1192:             * @return A HashMap with all relevant id-to-
1193:             *  name mappings has been returned.
1194:             ****/
1195:
1196:            private HashMap loadIdMappings(Statement stmt, Connection conn)
1197:                    throws Exception {
1198:
1199:                HashMap idToNameMap = new HashMap();
1200:
1201:                // Table ids.
1202:                ResultSet rs = stmt
1203:                        .executeQuery("select tableid, tablename from sys.systables");
1204:                while (rs.next())
1205:                    idToNameMap.put(rs.getString(1), rs.getString(2));
1206:
1207:                // Schema ids.
1208:                rs = stmt
1209:                        .executeQuery("select schemaid, schemaname from sys.sysschemas");
1210:                while (rs.next())
1211:                    idToNameMap.put(rs.getString(1), rs.getString(2));
1212:
1213:                // Constraint ids.
1214:                rs = stmt
1215:                        .executeQuery("select constraintid, constraintname from "
1216:                                + "sys.sysconstraints");
1217:                while (rs.next())
1218:                    idToNameMap.put(rs.getString(1), rs.getString(2));
1219:
1220:                return idToNameMap;
1221:
1222:            }
1223:
1224:            /* **********************************************
1225:             * getDependsData:
1226:             * Forms a string containing detailed information
1227:             * about a row in the SYSDEPENDS table, and returns
1228:             * that string.
1229:             * @param rs Result set with SYSDEPENDS rows; current
1230:             *  row is the one for which we're getting the
1231:             *  data.
1232:             * @param conn Connection to the database being
1233:             *   examined.
1234:             * @param idToNameMap mapping of object ids to names
1235:             *  for the database in question.
1236:             * @return Schema, type and name of both the Provider
1237:             *   and the Dependent for the current row of
1238:             *   SYSDEPENDS have been returned as a string.
1239:             ****/
1240:
1241:            private String getDependsData(ResultSet rs, Connection conn,
1242:                    HashMap idToNameMap) throws Exception {
1243:
1244:                DependableFinder dep = (DependableFinder) rs.getObject(3);
1245:
1246:                DependableFinder prov = (DependableFinder) rs.getObject(5);
1247:
1248:                String depType = dep.getSQLObjectType();
1249:                String provType = prov.getSQLObjectType();
1250:
1251:                Statement dependsStmt = conn.createStatement();
1252:                StringBuffer dependsData = new StringBuffer();
1253:                dependsData.append(getHiddenDependsData(depType, rs
1254:                        .getString(2), dependsStmt, idToNameMap));
1255:                dependsData.append(" -> ");
1256:                dependsData.append(getHiddenDependsData(provType, rs
1257:                        .getString(4), dependsStmt, idToNameMap));
1258:
1259:                return dependsData.toString();
1260:
1261:            }
1262:
1263:            /* **********************************************
1264:             * getHiddenDependsData:
1265:             * Returns a string containing the schema and
1266:             * name of the object having the received id.
1267:             * All object ids received by this message come
1268:             * from rows of the SYSDEPENDS table.
1269:             * @param type Type of the object that has the received
1270:             *   object id.
1271:             * @param id Id of the object in question.
1272:             * @param stmt Statement from the database in question.
1273:             * @param idToNameMap mapping of ids to names for
1274:             *  the database in question.
1275:             * @isProvider True if we're getting data for a
1276:             *  Provider object; false if we're getting data for
1277:             *  a Dependent object.
1278:             * @return Schema, type, and name for the object with
1279:             *   the received id have been returned as a string.
1280:             ****/
1281:
1282:            private String getHiddenDependsData(String type, String id,
1283:                    Statement pStmt, HashMap idToNameMap) throws Exception {
1284:
1285:                ResultSet rs = null;
1286:                if (type.equals("Constraint")) {
1287:                    rs = pStmt
1288:                            .executeQuery("select schemaid, constraintname from "
1289:                                    + "sys.sysconstraints where "
1290:                                    + "constraintid = '" + id + "'");
1291:                } else if (type.equals("StoredPreparedStatement")) {
1292:                    rs = pStmt.executeQuery("select schemaid, stmtname from "
1293:                            + "sys.sysstatements where stmtid = '" + id + "'");
1294:                } else if (type.equals("Trigger")) {
1295:                    rs = pStmt
1296:                            .executeQuery("select schemaid, triggername from "
1297:                                    + "sys.systriggers where triggerid = '"
1298:                                    + id + "'");
1299:                } else if (type.equals("View") || type.equals("Table")
1300:                        || type.equals("ColumnsInTable")) {
1301:                    rs = pStmt.executeQuery("select schemaid, tablename from "
1302:                            + "sys.systables where tableid = '" + id + "'");
1303:                } else if (type.equals("Conglomerate")) {
1304:                    rs = pStmt
1305:                            .executeQuery("select schemaid, conglomeratename from "
1306:                                    + "sys.sysconglomerates where conglomerateid = '"
1307:                                    + id + "'");
1308:                } else {
1309:                    System.out.println("WARNING: Unexpected "
1310:                            + "dependent type: " + type);
1311:                    return "";
1312:                }
1313:
1314:                if (rs.next()) {
1315:                    String schema = (String) idToNameMap.get(rs.getString(1));
1316:                    if (isIgnorableSchema(schema))
1317:                        // system object (so we want to ignore it); indicate
1318:                        // this by returning the string "SYS_OBJECT".
1319:                        return "SYS_OBJECT";
1320:                    StringBuffer result = new StringBuffer();
1321:                    result.append("<");
1322:                    result.append(type);
1323:                    result.append(">");
1324:                    result.append(schema);
1325:                    result.append(".");
1326:                    if (isSystemGenerated(rs.getString(2)))
1327:                        result.append("<sysname>");
1328:                    else
1329:                        result.append(rs.getString(2));
1330:                    return result.toString();
1331:                }
1332:
1333:                return "";
1334:
1335:            }
1336:
1337:            /* **********************************************
1338:             * deleteDB:
1339:             * Deletes the database with the received name
1340:             * from the test directory.
1341:             * @param dbName Name of the database to be deleted.
1342:             * @return Database has been completely deleted;
1343:             *   if deletion failed for any reason, a message
1344:             *   saying so has been printed to output.
1345:             ****/
1346:
1347:            private void deleteDB(String dbName) throws Exception {
1348:
1349:                // Get the full path.
1350:                String deletePath = (new File(dbPath + separator + dbName))
1351:                        .getAbsolutePath();
1352:
1353:                // Have to shut it down before we can delete it.
1354:                try {
1355:                    Connection conn = DriverManager.getConnection("jdbc:derby:"
1356:                            + deletePath + ";shutdown=true");
1357:                    conn.close();
1358:                } catch (SQLException se) {
1359:                    // shutdown exception.
1360:                }
1361:
1362:                File f = new File(deletePath);
1363:                if (!f.exists())
1364:                    // nothing to do.
1365:                    return;
1366:
1367:                File[] files = f.listFiles();
1368:                for (int i = 0; i < files.length; i++)
1369:                    deleteFile(files[i]);
1370:
1371:                if (!f.delete()) {
1372:                    // still failed.
1373:                    System.out.println("ERROR: deleting: " + f.getName());
1374:                }
1375:
1376:                // And finally, delete the CSJARS directory,
1377:                // if there is one.
1378:                deleteFile(new File(System.getProperty("user.dir") + separator
1379:                        + "CSJARS"));
1380:
1381:                System.out.println("Database '" + dbName + "' deleted.");
1382:                return;
1383:
1384:            }
1385:
1386:            /* **********************************************
1387:             * deleteFile:
1388:             * Delete everything in a given directory, then
1389:             * delete the directory itself (recursive).
1390:             * @param aFile File object representing the directory
1391:             *  to be deleted.
1392:             * @return the directory corresponding to aFile
1393:             *  has been deleted, as have all of its contents.
1394:             ****/
1395:
1396:            private void deleteFile(File aFile) throws Exception {
1397:
1398:                if (!aFile.exists())
1399:                    // don't bother.
1400:                    return;
1401:
1402:                if (aFile.delete())
1403:                    // just a file; we're done.
1404:                    return;
1405:
1406:                // Otherwise, have to descend and delete all
1407:                // files in this directory.
1408:                File[] files = aFile.listFiles();
1409:                if (files != null) {
1410:                    for (int i = 0; i < files.length; i++)
1411:                        deleteFile(files[i]);
1412:                }
1413:
1414:                // Now try to delete.
1415:                if (!aFile.delete()) {
1416:                    // still failed.
1417:                    System.out.println("ERROR: deleting: " + aFile.getName());
1418:                }
1419:
1420:                return;
1421:
1422:            }
1423:
1424:            /* **********************************************
1425:             * dumpFileToSysOut:
1426:             * Checks to see if the received file is empty,
1427:             * and prints a message saying so.
1428:             * @param fName Name of the file to be written to output.
1429:             * @return The contents of the specified file have
1430:             *   been written to System.out.
1431:             ****/
1432:
1433:            private void dumpFileToSysOut(String fName) {
1434:
1435:                try {
1436:
1437:                    BufferedReader dumpFile = new BufferedReader(
1438:                            new FileReader(fName));
1439:
1440:                    String line = dumpFile.readLine();
1441:                    if (line != null) {
1442:                        System.out
1443:                                .println("File "
1444:                                        + fName
1445:                                        + " was NOT "
1446:                                        + "empty.  Contents are:\n"
1447:                                        + "############## Begin File Contents ################\n");
1448:                        do {
1449:                            System.out.println(line);
1450:                            line = dumpFile.readLine();
1451:                        } while (line != null);
1452:                        System.out
1453:                                .println("############## End File Contents ################");
1454:                    } else
1455:                        System.out.println("File " + fName + " was empty.");
1456:
1457:                    // Close the file.
1458:                    dumpFile.close();
1459:
1460:                } catch (Exception e) {
1461:                    System.out.println("FAILED: to dump file '" + fName + "'");
1462:                    e.printStackTrace(System.out);
1463:                }
1464:
1465:                return;
1466:
1467:            }
1468:
1469:            /* **********************************************
1470:             * isSystemGenerated:
1471:             * Returns true if the received string looks like
1472:             * it is a system-generated string.  We assume
1473:             * it's system-generated if either 1) it starts
1474:             * with the letters "SQL", in which case it's a
1475:             * system-name, or 2) it has a dash in it, in which
1476:             * case it's a system id.
1477:             * @param str The string to check.
1478:             * @return True if we assume the string is system-
1479:             *  generated, false otherwise.
1480:             ****/
1481:
1482:            private boolean isSystemGenerated(String str) {
1483:
1484:                return (looksLikeSysGenName(str) || looksLikeSysGenId(str));
1485:
1486:            }
1487:
1488:            /* **********************************************
1489:             * looksLikeSysGenName:
1490:             * See if the received string looks like it is
1491:             * a system-generated name.  There are two types
1492:             * of system-generated names: 1) visible names,
1493:             * which start with "SQL", and 2) hidden names,
1494:             * which exist for Stored Statements that are
1495:             * used to back triggers; these names start with
1496:             * "TRIGGERACTN_" and then have a UUID.
1497:             * NOTE: This test assumes that none of object names
1498:             * provided in "dblook_makeDB.sql" satisfy
1499:             * either of these conditions.  If they do, they
1500:             * will be filtered out of the test output.
1501:             * @param val The string value in question.
1502:             * @return True if the value looks like it is a system-
1503:             *  generated name; false otherwise.
1504:             ****/
1505:
1506:            private boolean looksLikeSysGenName(String val) {
1507:
1508:                return ((val != null) && ((val.trim().indexOf("SQL") == 0) || // case 1.
1509:                ((val.trim().indexOf("TRIGGERACTN_") == 0) && // case 2.
1510:                (val.indexOf("-") != -1))));
1511:
1512:            }
1513:
1514:            /* **********************************************
1515:             * looksLikeSysGenId:
1516:             * See if the received string looks like it is
1517:             * a system-generated id (i.e. contains a dash (-)).
1518:             * NOTE: This test assumes that none of object names
1519:             * provided in "dblook_makeDB.sql" will contain
1520:             * dashes.  If they do, then they will be filtered out
1521:             * in the test output.
1522:             * @param val The string value in question.
1523:             * @return True if the value looks like it is a system-
1524:             *  generated id; false otherwise.
1525:             ****/
1526:
1527:            private boolean looksLikeSysGenId(String val) {
1528:
1529:                return ((val != null) && (val.indexOf("-") != -1));
1530:
1531:            }
1532:
1533:            /* **********************************************
1534:             * columnHoldsObjectName:
1535:             * Return true if the received column, which is from
1536:             * some system table, holds the _name_ of a database
1537:             * object (table, constraint, etc.).  Typically, we
1538:             * can just look for the keyword "NAME"; the exception
1539:             * is aliases, where the name is held in a column called
1540:             * ALIAS.
1541:             * @param colName Name of the column in question.
1542:             * @return True if the column name indicates that it
1543:             *  holds the _name_ of a database object; false if the
1544:             *  column name indicates that it holds something else.
1545:             ****/
1546:
1547:            private boolean columnHoldsObjectName(String colName) {
1548:
1549:                return (colName.equals("ALIAS") || (colName.indexOf("NAME") != -1));
1550:
1551:            }
1552:
1553:            /* **********************************************
1554:             * printAsHeader:
1555:             * Print the received string to output as a
1556:             * header.
1557:             * @param str String to print.
1558:             ****/
1559:
1560:            private void printAsHeader(String str) {
1561:
1562:                writeOut("--\n*******************************************");
1563:                writeOut(str);
1564:                writeOut("*******************************************\n");
1565:                return;
1566:
1567:            }
1568:
1569:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.