KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > derbyTesting > functionTests > tests > tools > dblook_test


1 /*
2
3    Derby - Class org.apache.derbyTesting.functionTests.tests.tools.dblook_test
4
5    Licensed to the Apache Software Foundation (ASF) under one or more
6    contributor license agreements. See the NOTICE file distributed with
7    this work for additional information regarding copyright ownership.
8    The ASF licenses this file to You under the Apache License, Version 2.0
9    (the "License"); you may not use this file except in compliance with
10    the License. You may obtain a copy of the License at
11
12       http://www.apache.org/licenses/LICENSE-2.0
13
14    Unless required by applicable law or agreed to in writing, software
15    distributed under the License is distributed on an "AS IS" BASIS,
16    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17    See the License for the specific language governing permissions and
18    limitations under the License.
19
20  */

21
22 package org.apache.derbyTesting.functionTests.tests.tools;
23
24 import java.sql.DriverManager JavaDoc;
25 import java.sql.ResultSet JavaDoc;
26 import java.sql.Connection JavaDoc;
27 import java.sql.Statement JavaDoc;
28 import java.sql.PreparedStatement JavaDoc;
29 import java.sql.ResultSetMetaData JavaDoc;
30 import java.sql.SQLException JavaDoc;
31 import java.sql.SQLWarning JavaDoc;
32 import java.sql.Timestamp JavaDoc;
33
34 import java.io.PrintWriter JavaDoc;
35 import java.io.FileOutputStream JavaDoc;
36 import java.io.FileNotFoundException JavaDoc;
37 import java.io.BufferedReader JavaDoc;
38 import java.io.FileReader JavaDoc;
39 import java.io.File JavaDoc;
40
41 import org.apache.derby.tools.dblook;
42 import org.apache.derby.tools.ij;
43 import org.apache.derby.catalog.DependableFinder;
44 import org.apache.derbyTesting.functionTests.util.TestUtil;
45
46
47
48 import java.util.HashMap JavaDoc;
49 import java.util.TreeMap JavaDoc;
50 import java.util.Set JavaDoc;
51 import java.util.Iterator JavaDoc;
52 import java.util.ArrayList JavaDoc;
53 import java.util.StringTokenizer JavaDoc;
54
55 public class dblook_test {
56
57     private static final int SERVER_PORT = 1527;
58     private static final int FRONT = -1;
59     private static final int REAR = 1;
60
61     protected static final String JavaDoc dbCreationScript_1 = "dblook_makeDB.sql";
62     protected static final String JavaDoc dbCreationScript_2 = "dblook_makeDB_2.sql";
63     private static final char TEST_DELIMITER='#';
64
65     protected static String JavaDoc testDirectory = "dblook_test";
66     protected static final String JavaDoc testDBName = "wombat";
67     protected static String JavaDoc separator;
68
69     private static String JavaDoc dbPath;
70     private static int duplicateCounter = 0;
71     private static int sysNameCount = 0;
72     private static String JavaDoc jdbcProtocol;
73
74     /* **********************************************
75      * main:
76      ****/

77
78     public static void main (String JavaDoc[] args) {
79
80         separator = System.getProperty("file.separator");
81         new dblook_test().doTest();
82         System.out.println("\n[ Done. ]\n");
83
84     }
85
86     /* **********************************************
87      * doTest
88      * Run a full test of the dblook utility.
89      ****/

90
91     protected void doTest() {
92
93         try {
94
95             // Test full dblook functionality.
96
System.out.println("\n-= Start dblook Functional Tests. =-");
97             createTestDatabase(dbCreationScript_1);
98             runDBLook(testDBName);
99
100             // Test dblook messages.
101
System.out.println("\n-= Start dblook Message Tests =-");
102             createTestDatabase(dbCreationScript_2);
103             runMessageCheckTest(testDBName);
104
105         } catch (SQLException JavaDoc se) {
106
107             System.out.println("FAILED: to complete the test:");
108             se.printStackTrace(System.out);
109             for (se = se.getNextException(); se != null;
110                 se = se.getNextException())
111             {
112                 se.printStackTrace(System.out);
113             }
114         
115         } catch (Exception JavaDoc e) {
116
117             System.out.println("FAILED: to complete the test:");
118             e.printStackTrace(System.out);
119
120         }
121
122     }
123
124     /* **********************************************
125      * createTestDatabase:
126      * Using the creation script created as part of
127      * the test package, create the database that
128      * will be used as the basis for all dblook
129      * tests.
130      * @param scriptName The name of the sql script
131      * to use for creating the test database.
132      * @return The test database has been created
133      * in the current test directory, which is
134      * "./dblook/" (as created by the harness).
135      ****/

136
137     protected void createTestDatabase(String JavaDoc scriptName)
138         throws Exception JavaDoc
139     {
140
141         // Delete existing database, if it exists.
142
try {
143             deleteDB(testDBName);
144         } catch (Exception JavaDoc e) {
145             System.out.println("** Warning: failed to delete " +
146                 "old test db before creating a new one...");
147         }
148
149         Class.forName("org.apache.derby.jdbc.EmbeddedDriver").newInstance();
150         jdbcProtocol = "jdbc:derby:";
151         createDBFromDDL(testDBName, scriptName);
152
153         // Figure out where our database directory is (abs path).
154
String JavaDoc systemhome = System.getProperty("derby.system.home");
155         dbPath = systemhome + File.separatorChar;
156         return;
157
158     }
159
160     /* **********************************************
161      * runDBLook:
162      * Runs a series of tests using dblook on
163      * the received database.
164      * @param dbName The name of the database on which to
165      * run the tests.
166      * @return A series of tests intended to verify
167      * the full functionality of the dblook utility
168      * has been run.
169      ****/

170
171     private void runDBLook(String JavaDoc dbName)
172         throws Exception JavaDoc
173     {
174
175         // Close the error stream, so that messages
176
// printed to System.err aren't intermixed
177
// with our output (otherwise, the order
178
// of the System.out vs System.err is
179
// arbitrary (because of the way the harness
180
// works), and so we will get diffs with
181
// the master.
182
System.err.close();
183
184         // First, we dump all system catalogs for
185
// the original source database to file.
186
dumpSysCatalogs(dbName);
187
188         // Then, we run dblook on the source database
189
// with no limitations (i.e. we generate the
190
// DDL for the FULL database).
191
lookOne(dbName);
192         dumpFileToSysOut("dblook.log");
193
194         // Now, create new db from the DDL that
195
// was generated by dblook.
196
String JavaDoc newDBName = dbName + "_new";
197         createDBFromDDL(newDBName, dbName + ".sql");
198         deleteFile(new File JavaDoc(dbName + ".sql"));
199
200         // Dump all system catalogs for the database
201
// that was created from the DDL generated
202
// by dblook.
203
dumpSysCatalogs(newDBName);
204
205         // Delete the new database.
206
deleteDB(newDBName);
207         deleteFile(new File JavaDoc(newDBName + ".sql"));
208
209         // Run dblook on the source database
210
// with various parameter configurations,
211
// to make sure they are all working as
212
// planned.
213
runAllTests(dbName, newDBName);
214
215     }
216
217     /* **********************************************
218      * runAllTests:
219      * Makes the call to execute each of the desired
220      * tests.
221      * @param dbName The name of the database on which to
222      * run the tests.
223      * @param newDBName The name of the database to be
224      * created from the DDL that is generated (by
225      * dblook) for the source database.
226      ****/

227
228     protected void runAllTests(String JavaDoc dbName,
229         String JavaDoc newDBName) throws Exception JavaDoc
230     {
231
232         runTest(2, dbName, newDBName);
233
234         // Test 3 is run as part of derbynet suite;
235
// see derbynet/dblook_test_net.java.
236

237         runTest(4, dbName, newDBName);
238         runTest(5, dbName, newDBName);
239         runTest(7, dbName, newDBName);
240         runTest(6, dbName, newDBName);
241         return;
242
243     }
244
245     /* **********************************************
246      * runTest:
247      * Runs dblook on the source database with a
248      * specific set of parameters, then uses the
249      * resultant DDL to create a new database, and
250      * dumps the system catalogs for that database
251      * to file. Finally, the new database is deleted
252      * in preparation for subsequent calls to this
253      * method.
254      * @param whichTest An indication of which test to run;
255      * each test number has a different set of
256      * parameters.
257      * @param dbName The name of the source database.
258      * @param newDBName The name of the database to be
259      * created from the DDL that is generated (by
260      * dblook) for the source database.
261      * @return dblook has been executed using the
262      * parameters associated with the given test,
263      * and that DDL has been written to a ".sql"
264      * file named after the source database;
265      * a new database has been created from the
266      * ".sql" generated by dblook; the system
267      * catalogs for that new database have been
268      * dumped to output; and the new database has
269      * been deleted.
270      ****/

271
272     protected void runTest(int whichTest, String JavaDoc dbName,
273         String JavaDoc newDBName)
274     {
275
276         try {
277
278             switch(whichTest) {
279                 case 2: lookTwo(dbName); break;
280                 case 3: lookThree(dbName); break;
281                 case 4: lookFour(dbName); break;
282                 case 5: lookFive(dbName); break;
283                 case 6: lookSix(dbName); break;
284                 case 7: lookSeven(dbName); break;
285                 default: break;
286             }
287
288             dumpFileToSysOut("dblook.log");
289             createDBFromDDL(newDBName, dbName + ".sql");
290             dumpSysCatalogs(newDBName);
291             deleteDB(newDBName);
292             deleteFile(new File JavaDoc(dbName + ".sql"));
293
294         } catch (SQLException JavaDoc e) {
295
296             System.out.println("FAILED: Test # : " + whichTest);
297             e.printStackTrace(System.out);
298             for (e = e.getNextException(); e != null;
299                 e = e.getNextException())
300             {
301                 e.printStackTrace(System.out);
302             }
303
304         } catch (Exception JavaDoc e) {
305
306             System.out.println("FAILED: Test # : " + whichTest);
307             e.printStackTrace(System.out);
308
309         }
310
311         return;
312
313     }
314
315     /* **********************************************
316      * lookOne:
317      * Use dblook to generate FULL DDL for a given
318      * database.
319      * @param dbName The name of the source database (i.e.
320      * the database for which the DDL is generated).
321      * @return The full DDL for the source database
322      * has been generated and written to a file
323      * called <dbName + ".sql">.
324      ****/

325
326     private void lookOne(String JavaDoc dbName)
327         throws Exception JavaDoc
328     {
329
330         printAsHeader("\nDumping full schema for '" +
331             dbName + "'\nto file '" + dbName + ".sql':\n");
332
333         String JavaDoc [] args = new String JavaDoc[] {
334             "-o", dbName + ".sql",
335             "-td", ""
336         };
337
338         go(dbName, args);
339         return;
340
341     }
342
343     /* **********************************************
344      * lookTwo:
345      * Use dblook to generate DDL for all objects
346      * in the source database with schema 'BAR',
347      * excluding views:
348      * -z bar -noview
349      * @param dbName The name of the source database (i.e.
350      * the database for which the DDL is generated).
351      * @return The appropriate DDL has been generated
352      * and written to a file called <dbName + ".sql">.
353      ****/

354
355     private void lookTwo(String JavaDoc dbName)
356         throws Exception JavaDoc
357     {
358
359         printAsHeader("\nDumping DDL for all objects " +
360             "with schema\n'BAR', excluding views:\n");
361  
362         String JavaDoc [] args = new String JavaDoc[] {
363             "-o", dbName + ".sql",
364             "-td", "",
365             "-z", "bar",
366             "-noview"
367         };
368
369         go(dbName, args);
370         return;
371
372     }
373
374     /* **********************************************
375      * lookThree:
376      * Use dblook to generate DDL for all objects
377      * in the source database, using Network
378      * Server.
379      * @param dbName The name of the source database (i.e.
380      * the database for which the DDL is generated).
381      * @return The appropriate DDL has been generated
382      * and written to a file called <dbName + ".sql">.
383      ****/

384
385     private void lookThree(String JavaDoc dbName)
386         throws Exception JavaDoc
387     {
388
389         printAsHeader("\nDumping DDL for all objects, " +
390             "using\nNetwork Server:\n");
391         String JavaDoc hostName = TestUtil.getHostName();
392         jdbcProtocol = TestUtil.getJdbcUrlPrefix(hostName,SERVER_PORT);
393
394         String JavaDoc sourceDBUrl;
395         if (TestUtil.isJCCFramework())
396             sourceDBUrl = jdbcProtocol + "\"" + dbPath +
397                 separator + dbName + "\":user=someusr;password=somepwd;";
398         else
399             sourceDBUrl = jdbcProtocol + dbPath +
400             separator + dbName + ";user=someusr;password=somepwd";
401
402         // Make sure we're not connected to the database
403
// (we connected to it in embedded mode when we
404
// created it, so we have to shut it down).
405
try {
406             DriverManager.getConnection(
407                 "jdbc:derby:" + dbName + ";shutdown=true");
408         } catch (SQLException JavaDoc e) {}
409
410         // Run the test.
411
try {
412
413             new dblook(new String JavaDoc[] {
414                 "-d", sourceDBUrl,
415                 "-o", dbName + ".sql",
416                 "-td", "" }
417             );
418
419         } catch (Exception JavaDoc e) {
420             System.out.println("FAILED: ");
421             e.printStackTrace(System.out);
422         }
423
424         return;
425
426     }
427
428     /* **********************************************
429      * lookFour:
430      * Use dblook to generate DDL for all objects
431      * in the source database with schema 'BAR'
432      * that are related to tables 'T3', 'tWithKeys',
433      * and 'MULTI WORD NAME'.
434      * -z bar -t t3 "\"tWithKeys\"" "Multi word name"
435      * @param dbName The name of the source database (i.e.
436      * the database for which the DDL is generated).
437      * @return The appropriate DDL has been generated
438      * and written to a file called <dbName + ".sql">.
439      ****/

440
441     private void lookFour(String JavaDoc dbName)
442         throws Exception JavaDoc
443     {
444
445         printAsHeader("\nDumping DDL for all objects " +
446             "with schema 'BAR'\nthat are related to tables " +
447             "'T3', 'tWithKeys',\nand 'MULTI WORD NAME':\n");
448  
449         String JavaDoc [] args = new String JavaDoc [] {
450             "-o", dbName + ".sql",
451             "-td", "",
452             "-z", "BAR",
453             "-t", "t3", "\"tWithKeys\"", "Multi word name"
454         };
455
456         go(dbName, args);
457         return;
458
459     }
460
461     /* **********************************************
462      * lookFive:
463      * Use dblook to generate DDL for all objects
464      * in the source database (with any schema)
465      * that are related to table 'T1' and 'TWITHKEYS'
466      * (with no matches existing for the latter).
467      * -t t1 "tWithKeys"
468      * @param dbName The name of the source database (i.e.
469      * the database for which the DDL is generated).
470      * @return The appropriate DDL has been generated
471      * and written to a file called <dbName + ".sql">.
472      ****/

473
474     private void lookFive(String JavaDoc dbName)
475         throws Exception JavaDoc
476     {
477
478         printAsHeader("\nDumping DDL for all objects " +
479             "related to 'T1'\nand 'TWITHKEYS':\n");
480  
481         String JavaDoc [] args = new String JavaDoc [] {
482             "-o", dbName + ".sql",
483             "-td", "",
484             "-t", "t1", "tWithKeys"
485         };
486
487         go(dbName, args);
488         return;
489
490     }
491
492     /* **********************************************
493      * lookSix:
494      * Call dblook with an invalid url, to make
495      * sure that errors are printed to log.
496      * -d <dbName> // missing protocol.
497      * @param dbName The name of the source database (i.e.
498      * the database for which the DDL is generated).
499      * @return The appropriate DDL has been generated
500      * and written to a file called <dbName + ".sql">.
501      ****/

502
503     private void lookSix(String JavaDoc dbName)
504         throws Exception JavaDoc
505     {
506
507         printAsHeader("\nDumping DDL w/ invalid url, and " +
508             "writing\nerror to the log:\n");
509  
510         // Url is intentionally incorrect; it will cause an error.
511
new dblook(new String JavaDoc[] {
512             "-o", dbName + ".sql",
513             "-d", dbName }
514         );
515
516     }
517
518     /* **********************************************
519      * lookSeven:
520      * Use dblook to generate DDL for all objects
521      * in the source database with schema '"Quoted"Schema"'.
522      * -z \"\"Quoted\"Schema\"\"
523      * @param dbName The name of the source database (i.e.
524      * the database for which the DDL is generated).
525      * @return The appropriate DDL has been generated
526      * and written to a file called <dbName + ".sql">.
527      ****/

528
529     private void lookSeven(String JavaDoc dbName)
530         throws Exception JavaDoc
531     {
532
533         printAsHeader("\nDumping DDL for all objects " +
534             "with schema\n'\"Quoted\"Schema\"':\n");
535  
536         String JavaDoc [] args = new String JavaDoc[] {
537             "-o", dbName + ".sql",
538             "-td", "",
539             "-z", "\"\"Quoted\"Schema\"\""
540         };
541
542         go(dbName, args);
543         return;
544
545     }
546
547     /* **********************************************
548      * go:
549      * Makes the call to execute the dblook command
550      * using the received arguments.
551      * @param dbName The name of the source database (i.e.
552      * the database for which the DDL is generated).
553      * @args The list of arguments with which to execute
554      * the dblook command.
555      ****/

556
557     private void go(String JavaDoc dbName, String JavaDoc [] args) {
558
559         jdbcProtocol = "jdbc:derby:";
560         String JavaDoc sourceDBUrl = jdbcProtocol + dbPath +
561             separator + dbName;
562
563         String JavaDoc [] fullArgs = new String JavaDoc[args.length+2];
564         fullArgs[0] = "-d";
565         fullArgs[1] = sourceDBUrl;
566         for (int i = 2; i < fullArgs.length; i++)
567             fullArgs[i] = args[i-2];
568
569         try {
570             new dblook(fullArgs);
571         } catch (Exception JavaDoc e) {
572             System.out.println("FAILED: to run dblook: ");
573             e.printStackTrace(System.out);
574         }
575
576     }
577
578     /* **********************************************
579      * runMessageCheckTest
580      * Run dblook and verify that all of the dblook
581      * messages are correctly displayed.
582      * @param dbName The name of the source database (i.e.
583      * the database for which the DDL is generated).
584      * @return The DDL for a simple database, plus all
585      * dblook messages, have been generated and written
586      * to System.out.
587      ****/

588     private void runMessageCheckTest(String JavaDoc dbName)
589         throws Exception JavaDoc
590     {
591
592         // #1: First, run DB look standard to check for
593
// all of the "header" messages that are printed
594
// out along with DDL.
595
System.out.println("\n************\n" +
596             "Msg Test 1\n" +
597             "************\n");
598         lookOne(dbName);
599         dumpFileToSysOut(dbName + ".sql");
600         dumpFileToSysOut("dblook.log");
601
602         // Now, we have to run some additional dblook commands
603
// to get the "non-standard" messages.
604

605         // #2: Specify a target table and target schema, to
606
// make sure they are echoed correctly. Also, specify
607
// an output file to make sure the file creation header
608
// is printed in the file.
609
System.out.println(
610             "\n************\n" +
611             "Msg Test 2\n" +
612             "************\n");
613         go(dbName, new String JavaDoc [] {
614                 "-t", "t1",
615                 "-z", "bar",
616                 "-o", dbName + ".sql"
617             });
618         dumpFileToSysOut(dbName + ".sql");
619         dumpFileToSysOut("dblook.log");
620
621         // #3: Run without specifying a database, to make
622
// sure the usage message is printed to System.out
623
System.out.println(
624             "\n************\n" +
625             "Msg Test 3\n" +
626             "************\n");
627         try {
628             new dblook(new String JavaDoc[] { "-verbose" });
629         } catch (Exception JavaDoc e) {
630             System.out.println("FAILED: to run dblook: ");
631             e.printStackTrace(System.out);
632         }
633
634         // #4: Just to confirm, try once with a statement
635
// delimiter, to make sure it's actually working
636
// correctly (this isn't a "message" per se, but
637
// still, it's worth verifying).
638
System.out.println(
639             "\n************\n" +
640             "Msg Test 4\n" +
641             "************\n");
642         go(dbName, new String JavaDoc [] {
643                 "-td", " " + TEST_DELIMITER
644             });
645
646         // #5: Intentionally create an error while loading
647
// a jar file, to make sure the resultant message is
648
// printed correctly.
649
System.out.println(
650             "\n************\n" +
651             "Msg Test 5\n" +
652             "************\n");
653
654         // We'll cause the error by going in and deleting
655
// the jar file from the test database. First,
656
// get the jar path.
657
String JavaDoc jarPath = (new
658             File JavaDoc(dbPath + separator + dbName)).getAbsolutePath();
659
660         // Have to shut db down before we can mess with it.
661
try {
662             Connection JavaDoc conn =
663                 DriverManager.getConnection("jdbc:derby:" +
664                     jarPath + ";shutdown=true");
665             conn.close();
666         } catch (SQLException JavaDoc se) {
667         // shutdown exception.
668
}
669
670         jarPath = jarPath + separator + "jar";
671         deleteFile(new File JavaDoc(jarPath));
672
673         // Now that we've deleted the jar file, run dblook
674
// and check the error.
675
go(dbName, new String JavaDoc [] {
676                 "-verbose",
677                 "-o", dbName + ".sql"
678             });
679         dumpFileToSysOut("dblook.log");
680
681         // Clean up.
682
try {
683             deleteFile(new File JavaDoc(dbName + ".sql"));
684         } catch (Exception JavaDoc e) {
685         // not too big of a deal if we fail; just ignore...
686
}
687
688     }
689
690     /* **********************************************
691      * dumpSysCatalogs:
692      * Takes a database name and dumps ALL of the
693      * system catalogs for that database, with the
694      * exception of SYSSTATISTICS. This allows us
695      * to look at the full contents of a database's
696      * schema (without using dblook, of course)
697      * so that we can see if the databases created
698      * from the DDL generated by dblook have been
699      * built correctly--if they have all of the
700      * correct system catalog information, then
701      * the databases themselves must be correct.
702      * @param dbName The name of the database for which
703      * we are dumping the system catalogs.
704      * @return All of the system catalogs for
705      * the received database have been dumped
706      * to output.
707      ****/

708
709     private void dumpSysCatalogs(String JavaDoc dbName)
710         throws Exception JavaDoc
711     {
712
713         System.out.println("\nDumping system tables for '" + dbName + "'\n");
714
715         writeOut("\n----------------=================---------------");
716         writeOut("System Tables for: " + dbName);
717         writeOut("----------------=================---------------\n");
718
719         // Connect to the database.
720
Connection JavaDoc conn = DriverManager.getConnection(
721                 "jdbc:derby:" + dbName);
722         conn.setAutoCommit(false);
723         Statement JavaDoc stmt = conn.createStatement();
724
725         // Load any id-to-name mappings that will be useful
726
// when dumping the catalogs.
727
HashMap JavaDoc idToNameMap = loadIdMappings(stmt, conn);
728
729         // Go through and dump all system catalog information,
730
// filtering out database-dependent id's so that they
731
// won't cause diffs.
732

733         writeOut("\n========== SYSALIASES ==========\n");
734         ResultSet JavaDoc rs =
735             stmt.executeQuery("select schemaid, sys.sysaliases.* from sys.sysaliases");
736         dumpResultSet(rs, idToNameMap, null);
737
738         writeOut("\n========== SYSCHECKS ==========\n");
739         rs = stmt.executeQuery("select c.schemaid, ck.* from " +
740             "sys.syschecks ck, sys.sysconstraints c where " +
741             "ck.constraintid = c.constraintid");
742         dumpResultSet(rs, idToNameMap, null);
743
744         writeOut("\n========== SYSCOLUMNS ==========\n");
745         writeOut("--- Columns for Tables ---");
746         rs = stmt.executeQuery("select t.schemaid, c.* from " +
747             "sys.syscolumns c, sys.systables t where c.referenceid " +
748             "= t.tableid" );
749         dumpResultSet(rs, idToNameMap, null);
750         writeOut("\n--- Columns for Statements ---");
751         rs = stmt.executeQuery("select s.schemaid, c.* from " +
752             "sys.syscolumns c, sys.sysstatements s where c.referenceid " +
753             "= s.stmtid" );
754         dumpResultSet(rs, idToNameMap, null);
755
756         writeOut("\n========== SYSCONGLOMERATES ==========\n");
757         rs = stmt.executeQuery("select schemaid, sys.sysconglomerates.* " +
758             "from sys.sysconglomerates");
759         dumpResultSet(rs, idToNameMap, null);
760
761         writeOut("\n========== SYSCONSTRAINTS ==========\n");
762         rs = stmt.executeQuery("select schemaid, sys.sysconstraints.* " +
763             "from sys.sysconstraints");
764         dumpResultSet(rs, idToNameMap, null);
765
766         writeOut("\n========== SYSDEPENDS ==========\n");
767         rs = stmt.executeQuery("select dependentid, sys.sysdepends.* from sys.sysdepends");
768         dumpResultSet(rs, idToNameMap, conn);
769
770         writeOut("\n========== SYSFILES ==========\n");
771         rs = stmt.executeQuery("select schemaid, sys.sysfiles.* from sys.sysfiles");
772         dumpResultSet(rs, idToNameMap, null);
773
774         writeOut("\n========== SYSFOREIGNKEYS ==========\n");
775         rs = stmt.executeQuery("select c.schemaid, fk.* from " +
776             "sys.sysforeignkeys fk, sys.sysconstraints c where " +
777             "fk.constraintid = c.constraintid");
778         dumpResultSet(rs, idToNameMap, null);
779
780         writeOut("\n========== SYSKEYS ==========\n");
781         rs = stmt.executeQuery("select c.schemaid, k.* from " +
782             "sys.syskeys k, sys.sysconstraints c where " +
783             "k.constraintid = c.constraintid");
784         dumpResultSet(rs, idToNameMap, null);
785
786         writeOut("\n========== SYSSCHEMAS ==========\n");
787         rs = stmt.executeQuery("select schemaid, sys.sysschemas.* from sys.sysschemas");
788         dumpResultSet(rs, idToNameMap, null);
789
790         writeOut("\n========== SYSSTATEMENTS ==========\n");
791         rs = stmt.executeQuery("select schemaid, sys.sysstatements.* from sys.sysstatements");
792         dumpResultSet(rs, idToNameMap, null);
793
794         writeOut("\n========== SYSTABLES ==========\n");
795         rs = stmt.executeQuery("select schemaid, sys.systables.* from sys.systables");
796         dumpResultSet(rs, idToNameMap, null);
797
798         writeOut("\n========== SYSTRIGGERS ==========\n");
799         rs = stmt.executeQuery("select schemaid, sys.systriggers.* from sys.systriggers");
800         dumpResultSet(rs, idToNameMap, null);
801
802         writeOut("\n========== SYSVIEWS ==========\n");
803         rs = stmt.executeQuery("select compilationschemaid, sys.sysviews.* from sys.sysviews");
804         dumpResultSet(rs, idToNameMap, null);
805
806         stmt.close();
807         rs.close();
808         conn.commit();
809         conn.close();
810         return;
811
812     }
813
814     /* **********************************************
815      * isIgnorableSchema:
816      * Returns true if the the schema is a "system" schema, vs. a user
817      * schema.
818      * @param schemaName name of schema to check.
819      ****/

820     private boolean isIgnorableSchema(String JavaDoc schemaName) {
821
822         boolean ret = false;
823
824         for (int i = ignorableSchemaNames.length - 1; i >= 0;)
825         {
826             if ((ret = ignorableSchemaNames[i--].equalsIgnoreCase(schemaName)))
827                 break;
828         }
829
830         return(ret);
831     }
832
833     private static final String JavaDoc[] ignorableSchemaNames = {
834         "SYSIBM",
835         "SYS",
836         "SYSVISUAL",
837         "SYSCAT",
838         "SYSFUN",
839         "SYSPROC",
840         "SYSSTAT",
841         "NULLID",
842         "SYSCS_ADMIN",
843         "SYSCS_DIAG",
844         "SYSCS_UTIL",
845         "SQLJ"};
846
847     /* **********************************************
848      * dumpResultSet:
849      * Iterates through the received result set and
850      * dumps ALL columns in ALL rows of that result
851      * set to output. Since no order is guaranteed
852      * in the received result set, we have to generate
853      * unique "ids" for each row in the result, and
854      * then use those ids to determine what order the
855      * rows will be output. Failure to do so will
856      * lead to diffs in the test for rows that occur
857      * out of order. The unique id's must NOT
858      * depend on system-generated id's, as the
859      * latter will vary for every run of the test,
860      * and thus will lead to different orderings
861      * every time (which we don't want).
862      *
863      * @param rs The result set that is being dumped.
864      * @param idToNameMap Mapping of various ids to
865      * object names; used in forming unique ids.
866      * @param conn Connection from which the result set
867      * originated.
868      ****/

869
870     private void dumpResultSet (ResultSet JavaDoc rs,
871         HashMap JavaDoc idToNameMap, Connection JavaDoc conn)
872         throws Exception JavaDoc
873     {
874
875         // We need to form unique names for the rows of the
876
// result set so that we can preserve the order of
877
// the output and avoid diffs with a master. This is
878
// because a "select *" doesn't order rows--and even
879
// though the schema for two databases might be the
880
// same (i.e. the system tables contain all of the same
881
// information) there's nothing to say the various rows in
882
// the respective system tables will be the same (they
883
// usually are NOT). While system id's automatically
884
// give us uniqueness, we can NOT order on them because
885
// they vary from database to database; so, we need
886
// to use something constant across the databases,
887
// which is why we use object names.
888
StringBuffer JavaDoc uniqueName = new StringBuffer JavaDoc();
889
890         TreeMap JavaDoc orderedRows = new TreeMap JavaDoc();
891         ArrayList JavaDoc rowValues = new ArrayList JavaDoc();
892         ArrayList JavaDoc duplicateRowIds = new ArrayList JavaDoc();
893
894         ResultSetMetaData JavaDoc rsmd = rs.getMetaData();
895         int cols = rsmd.getColumnCount();
896         while (rs.next()) {
897
898             for (int i = 1; i <= cols; i++) {
899
900                 String JavaDoc colName = rsmd.getColumnName(i);
901                 String JavaDoc value = rs.getString(i);
902                 String JavaDoc mappedName = (String JavaDoc)idToNameMap.get(value);
903
904                 if ((colName.indexOf("SCHEMAID") != -1) &&
905                     (mappedName != null) &&
906                     ((mappedName.indexOf("SYS") != -1) ||
907                      (isIgnorableSchema(mappedName))))
908                 {
909                 // then this row of the result set is for a system
910
// object, which will always be the same for the
911
// source and new database, so don't bother dumping
912
// them to the output file (makes the test less
913
// like to require updates when changes to database
914
// metadata for system objects are checked in).
915
rowValues = null;
916                     break;
917                 }
918                 else if (colName.equals("JAVACLASSNAME") && (value != null) &&
919                     (value.indexOf("org.apache.derby") != -1) &&
920                     (value.indexOf(".util.") == -1)) {
921                 // this is a -- hack -- to see if the alias is a
922
// a system alias, needed because aliases
923
// (other than stored procedures) do not have
924
// an associated schema).
925
rowValues = null;
926                     break;
927                 }
928
929                 if (i == 1)
930                 // 1st column is just for figuring out whether
931
// to dump this row; no need to actually include
932
// it in the results.
933
continue;
934
935                 String JavaDoc uniquePiece = dumpColumnData(colName,
936                     value, mappedName, rowValues);
937
938                 if (colName.equals("DEPENDENTID")) {
939                 // Special case: rows in the "DEPENDS" table
940
// don't have unique ids or names; we have to
941
// build one by extracting information indirectly.
942
String JavaDoc hiddenInfo = getDependsData(rs, conn,
943                         idToNameMap);
944                     if (hiddenInfo.indexOf("SYS_OBJECT") != -1) {
945                     // this info is for a system object, so
946
// ignore it.
947
rowValues = null;
948                         break;
949                     }
950                     uniqueName.append(hiddenInfo);
951                     // Include the hidden data as part of the
952
// output.
953
rowValues.add(hiddenInfo);
954                 }
955
956                 if (uniquePiece != null)
957                     uniqueName.append(uniquePiece);
958
959                 if (colName.equals("STMTNAME") &&
960                   (value.indexOf("TRIGGERACTN") != -1))
961                 // Special case: can't use statement name, because
962
// the entire statement may be automatically generated
963
// in each database (to back a trigger), so the name
964
// in which case the generated name will be different
965
// every time; but filtering out the name means
966
// we have no other guaranteed unique 'id' for
967
// ordering. So, just take "text" field, and
968
// design test db so that no two triggers have the
969
// same text value.
970
uniqueName.append(rs.getString(6));
971
972             }
973
974             if (rowValues != null) {
975
976                 if (duplicateRowIds.contains(uniqueName.toString()))
977                 // then we've already encountered this row id before;
978
// to preserve ordering, use the entire row as an
979
// id.
980
handleDuplicateRow(rowValues, null, orderedRows);
981                 else {
982                     ArrayList JavaDoc oldRow = (ArrayList JavaDoc)(orderedRows.put(
983                         uniqueName.toString(), rowValues));
984                     if (oldRow != null) {
985                     // Duplicate row id.
986
duplicateRowIds.add(uniqueName.toString());
987                         // Delete the row that has the duplicate row id.
988
orderedRows.remove(uniqueName.toString());
989                         handleDuplicateRow(rowValues, oldRow, orderedRows);
990                     }
991                 }
992             }
993
994             uniqueName = new StringBuffer JavaDoc();
995             rowValues = new ArrayList JavaDoc();
996
997         }
998
999         // Now, print out all of the data in this result set
1000
// using the order of the unique names that we created.
1001
Set JavaDoc objectNames = orderedRows.keySet();
1002        for (Iterator JavaDoc itr = objectNames.iterator();
1003            itr.hasNext(); ) {
1004
1005            String JavaDoc row = (String JavaDoc)itr.next();
1006            ArrayList JavaDoc colData = (ArrayList JavaDoc)orderedRows.get(row);
1007            for (int i = 0; i < colData.size(); i++)
1008                writeOut((String JavaDoc)colData.get(i));
1009            writeOut("----");
1010
1011        }
1012
1013        orderedRows = null;
1014        rs.close();
1015
1016    }
1017
1018    /* **********************************************
1019     * dumpColumnData:
1020     * Stores the value for a specific column of
1021     * some result set. If the value needs to
1022     * be filtered (to remove system-generated ids
1023     * that would otherwise cause diffs with the
1024     * master), that filtering is done here.
1025     * @param colName Name of the column whose value we're
1026     * writing.
1027     * @param value Value that we're writing.
1028     * @param mappedName: Name corresponding to the value,
1029     * for cases where the value is actually an
1030     * object id (then we want to write the name
1031     * instead).
1032     * rowValues a list of column values for the
1033     * current row of the result set.
1034     * @return The (possibly filtered) value of the
1035     * received column has been added to the
1036     * "rowVals" array list, and the corresponding
1037     * piece of the row's unique name has been
1038     * returned, if one exists.
1039     ****/

1040
1041    private String JavaDoc dumpColumnData(String JavaDoc colName,
1042        String JavaDoc value, String JavaDoc mappedName, ArrayList JavaDoc rowVals)
1043    {
1044
1045        if (mappedName == null) {
1046        // probably not an id.
1047
if (colName.equals("CONGLOMERATENUMBER") ||
1048                colName.equals("GENERATIONID"))
1049            // special case: these numbers aren't ids per
1050
// se, but they are still generated by the system,
1051
// and will cause diffs with the master; so, ignore
1052
// them.
1053
rowVals.add("<systemnumber>");
1054            else if (colName.equals("AUTOINCREMENTVALUE"))
1055            // special case: new database won't have any data,
1056
// old will, so unless we filter this out, we'll
1057
// get a diff.
1058
rowVals.add("<autoincval>");
1059            else if (colName.equals("VALID"))
1060            // special case: ignore whether or not stored
1061
// statements are valid (have been compiled)
1062
// since it depends on history of database,
1063
// which we can't duplicate.
1064
rowVals.add("<validityflag>");
1065            else if (value != null) {
1066                if (looksLikeSysGenName(value)) {
1067                    if (columnHoldsObjectName(colName))
1068                        rowVals.add("<systemname>");
1069                    else {
1070                    // looks like a sys gen name, but's actually a VALUE.
1071
rowVals.add(value);
1072                        return value;
1073                    }
1074                }
1075                else if (looksLikeSysGenId(value))
1076                    rowVals.add("<systemid>");
1077                else {
1078                    rowVals.add(value);
1079                    if (columnHoldsObjectName(colName))
1080                    // if it's a name, we need it as part of
1081
// our unique id.
1082
return value;
1083                }
1084            }
1085            else
1086            // null value.
1087
rowVals.add(value);
1088        }
1089        else {
1090        // it's an id, so write the corresponding name.
1091
if (!isSystemGenerated(mappedName)) {
1092            // Not an id-as-name, so use it as part of our unique id.
1093
rowVals.add(mappedName);
1094                return mappedName;
1095            }
1096            else
1097                rowVals.add("<systemname>");
1098        }
1099
1100        // If we get here, we do NOT want the received value
1101
// to be treated as part of this row's unique name.
1102
return null;
1103
1104    }
1105
1106    /* **********************************************
1107     * handleDuplicateRow:
1108     * If we get here, then despite our efforts (while
1109     * dumping the system catalogs for a database), we
1110     * still have a duplicate row id. So, as a last
1111     * resort we just use the ENTIRE row as a 'row id'.
1112     * In the rare-but-possible case that the entire
1113     * row is a duplicate (as can happen with the
1114     * SYSDEPENDS table), then we tag a simple number
1115     * onto the latest row's id, so that the row will
1116     * still show up multiple times--and since the rows
1117     * are identical, it doesn't matter which comes
1118     * 'first'.
1119     * @param newRow The most recently-fetched row from
1120     * the database system catalogs.
1121     * @param oldRow The row that was replaced when the
1122     * newRow was inserted (because they had the
1123     * same row id), or "null" if we were already
1124     * here once for this row id, and so just want
1125     * insert a new row.
1126     * @param orderedRows The ordered set of rows, into
1127     * which oldRow and newRow need to be inserted.
1128     * @return oldRow and newRow have been inserted
1129     * into orderedRows, and each has a (truly)
1130     * unique id with it.
1131     ****/

1132
1133    private void handleDuplicateRow(
1134        ArrayList JavaDoc newRow, ArrayList JavaDoc oldRow,
1135        TreeMap JavaDoc orderedRows)
1136    {
1137
1138        // Add the received rows (old and new) with
1139
// unique row ids.
1140

1141        StringBuffer JavaDoc newRowId = new StringBuffer JavaDoc();
1142        for (int i = 0; i < newRow.size(); i++)
1143            newRowId.append((String JavaDoc)newRow.get(i));
1144
1145        Object JavaDoc obj = (ArrayList JavaDoc)(orderedRows.put(
1146                        newRowId.toString(), newRow));
1147        if (obj != null)
1148        // entire row is a duplicate.
1149
orderedRows.put(newRowId.toString() +
1150                duplicateCounter++, newRow);
1151
1152        if (oldRow != null) {
1153
1154            StringBuffer JavaDoc oldRowId = new StringBuffer JavaDoc();
1155            for (int i = 0; i < oldRow.size(); i++)
1156                oldRowId.append((String JavaDoc)oldRow.get(i));
1157
1158            obj = (ArrayList JavaDoc)(orderedRows.put(
1159                oldRowId.toString(), oldRow));
1160            if (obj != null)
1161            // entire row is a duplicate.
1162
orderedRows.put(oldRowId.toString() +
1163                    duplicateCounter++, oldRow);
1164        }
1165
1166        return;
1167
1168    }
1169
1170    /* **********************************************
1171     * createDBFromDDL:
1172     * Read from the given script and use it to create
1173     * a new database of the given name.
1174     * @param newDBName Name of the database to be created.
1175     * @param scriptName Name of the script containing the
1176     * DDL from which the new database will be created.
1177     * @return New database has been created from
1178     * the script; any commands in the script that
1179     * failed to execute have been echoed to output.
1180     ****/

1181
1182    private void createDBFromDDL(String JavaDoc newDBName,
1183        String JavaDoc scriptName) throws Exception JavaDoc
1184    {
1185
1186        System.out.println("\n\nCreating database '" + newDBName +
1187            "' from ddl script '" + scriptName + "'");
1188
1189        Connection JavaDoc conn = DriverManager.getConnection(
1190            "jdbc:derby:" + newDBName + ";create=true");
1191
1192        Statement JavaDoc stmt = conn.createStatement();
1193        BufferedReader JavaDoc ddlScript =
1194            new BufferedReader JavaDoc(new FileReader JavaDoc(scriptName));
1195
1196        for (String JavaDoc sqlCmd = ddlScript.readLine(); sqlCmd != null;
1197            sqlCmd = ddlScript.readLine()) {
1198
1199            if (sqlCmd.indexOf("--") == 0)
1200            // then this is a script comment; ignore it;
1201
continue;
1202            else if (sqlCmd.trim().length() == 0)
1203            // blank line; ignore it.
1204
continue;
1205
1206            // Execute the command.
1207
if ((sqlCmd.charAt(sqlCmd.length()-1) == TEST_DELIMITER)
1208              || (sqlCmd.charAt(sqlCmd.length()-1) == ';'))
1209            // strip off the delimiter.
1210
sqlCmd = sqlCmd.substring(0, sqlCmd.length()-1);
1211
1212            try {
1213                stmt.execute(sqlCmd);
1214            } catch (Exception JavaDoc e) {
1215                System.out.println("FAILED: to execute cmd " +
1216                    "from DDL script:\n" + sqlCmd + "\n");
1217                System.out.println(e.getMessage());
1218            }
1219
1220        }
1221
1222        // Cleanup.
1223
ddlScript.close();
1224        stmt.close();
1225        conn.close();
1226
1227        return;
1228
1229    }
1230
1231    /* **********************************************
1232     * writeOut:
1233     * Write the received string to some output.
1234     * @param str String to write.
1235     ****/

1236
1237    private static void writeOut(String JavaDoc str) {
1238
1239        System.out.println(str);
1240        return;
1241
1242    }
1243
1244    /* **********************************************
1245     * loadIdMappings:
1246     * Load mappings of object ids to object names
1247     * for purposes of having meaningful output
1248     * and for creating unique ids on the rows of
1249     * the system catalogs.
1250     * @param stmt Statement on a connection to the
1251     * database being examined.
1252     * @param conn Connection to the database being
1253     * examined.
1254     * @return A HashMap with all relevant id-to-
1255     * name mappings has been returned.
1256     ****/

1257
1258    private HashMap JavaDoc loadIdMappings(Statement JavaDoc stmt,
1259        Connection JavaDoc conn) throws Exception JavaDoc {
1260
1261        HashMap JavaDoc idToNameMap = new HashMap JavaDoc();
1262
1263        // Table ids.
1264
ResultSet JavaDoc rs = stmt.executeQuery(
1265            "select tableid, tablename from sys.systables");
1266        while (rs.next())
1267            idToNameMap.put(rs.getString(1), rs.getString(2));
1268
1269        // Schema ids.
1270
rs = stmt.executeQuery(
1271            "select schemaid, schemaname from sys.sysschemas");
1272        while (rs.next())
1273            idToNameMap.put(rs.getString(1), rs.getString(2));
1274
1275        // Constraint ids.
1276
rs = stmt.executeQuery(
1277            "select constraintid, constraintname from " +
1278            "sys.sysconstraints");
1279        while (rs.next())
1280            idToNameMap.put(rs.getString(1), rs.getString(2));
1281
1282        return idToNameMap;
1283
1284    }
1285
1286    /* **********************************************
1287     * getDependsData:
1288     * Forms a string containing detailed information
1289     * about a row in the SYSDEPENDS table, and returns
1290     * that string.
1291     * @param rs Result set with SYSDEPENDS rows; current
1292     * row is the one for which we're getting the
1293     * data.
1294     * @param conn Connection to the database being
1295     * examined.
1296     * @param idToNameMap mapping of object ids to names
1297     * for the database in question.
1298     * @return Schema, type and name of both the Provider
1299     * and the Dependent for the current row of
1300     * SYSDEPENDS have been returned as a string.
1301     ****/

1302
1303    private String JavaDoc getDependsData(ResultSet JavaDoc rs,
1304        Connection JavaDoc conn, HashMap JavaDoc idToNameMap)
1305        throws Exception JavaDoc
1306    {
1307
1308        DependableFinder dep =
1309            (DependableFinder)rs.getObject(3);
1310
1311        DependableFinder prov =
1312            (DependableFinder)rs.getObject(5);
1313
1314        String JavaDoc depType = dep.getSQLObjectType();
1315        String JavaDoc provType = prov.getSQLObjectType();
1316
1317        Statement JavaDoc dependsStmt = conn.createStatement();
1318        StringBuffer JavaDoc dependsData = new StringBuffer JavaDoc();
1319        dependsData.append(getHiddenDependsData(depType,
1320            rs.getString(2), dependsStmt, idToNameMap));
1321        dependsData.append(" -> ");
1322        dependsData.append(getHiddenDependsData(provType,
1323            rs.getString(4), dependsStmt, idToNameMap));
1324
1325        return dependsData.toString();
1326
1327    }
1328
1329    /* **********************************************
1330     * getHiddenDependsData:
1331     * Returns a string containing the schema and
1332     * name of the object having the received id.
1333     * All object ids received by this message come
1334     * from rows of the SYSDEPENDS table.
1335     * @param type Type of the object that has the received
1336     * object id.
1337     * @param id Id of the object in question.
1338     * @param stmt Statement from the database in question.
1339     * @param idToNameMap mapping of ids to names for
1340     * the database in question.
1341     * @isProvider True if we're getting data for a
1342     * Provider object; false if we're getting data for
1343     * a Dependent object.
1344     * @return Schema, type, and name for the object with
1345     * the received id have been returned as a string.
1346     ****/

1347
1348    private String JavaDoc getHiddenDependsData(String JavaDoc type,
1349        String JavaDoc id, Statement JavaDoc pStmt, HashMap JavaDoc idToNameMap)
1350        throws Exception JavaDoc
1351    {
1352
1353        ResultSet JavaDoc rs = null;
1354        if (type.equals("Constraint")) {
1355            rs = pStmt.executeQuery(
1356                "select schemaid, constraintname from " +
1357                "sys.sysconstraints where " +
1358                "constraintid = '" + id + "'");
1359        }
1360        else if (type.equals("StoredPreparedStatement")) {
1361            rs = pStmt.executeQuery(
1362                "select schemaid, stmtname from " +
1363                "sys.sysstatements where stmtid = '" +
1364                id + "'");
1365        }
1366        else if (type.equals("Trigger")) {
1367            rs = pStmt.executeQuery(
1368                "select schemaid, triggername from " +
1369                "sys.systriggers where triggerid = '" +
1370                id + "'");
1371        }
1372        else if (type.equals("View") || type.equals("Table")
1373          || type.equals("ColumnsInTable")) {
1374            rs = pStmt.executeQuery(
1375                "select schemaid, tablename from " +
1376                "sys.systables where tableid = '" +
1377                id + "'");
1378        }
1379        else if (type.equals("Conglomerate")) {
1380            rs = pStmt.executeQuery(
1381                "select schemaid, conglomeratename from " +
1382                "sys.sysconglomerates where conglomerateid = '" +
1383                id + "'");
1384        }
1385        else {
1386            System.out.println("WARNING: Unexpected " +
1387                "dependent type: " + type);
1388            return "";
1389        }
1390
1391        if (rs.next()) {
1392            String JavaDoc schema = (String JavaDoc)idToNameMap.get(rs.getString(1));
1393            if (isIgnorableSchema(schema))
1394            // system object (so we want to ignore it); indicate
1395
// this by returning the string "SYS_OBJECT".
1396
return "SYS_OBJECT";
1397            StringBuffer JavaDoc result = new StringBuffer JavaDoc();
1398            result.append("<");
1399            result.append(type);
1400            result.append(">");
1401            result.append(schema);
1402            result.append(".");
1403            if (isSystemGenerated(rs.getString(2)))
1404                result.append("<sysname>");
1405            else
1406                result.append(rs.getString(2));
1407            return result.toString();
1408        }
1409
1410        return "";
1411
1412    }
1413
1414    /* **********************************************
1415     * deleteDB:
1416     * Deletes the database with the received name
1417     * from the test directory.
1418     * @param dbName Name of the database to be deleted.
1419     * @return Database has been completely deleted;
1420     * if deletion failed for any reason, a message
1421     * saying so has been printed to output.
1422     ****/

1423
1424    private void deleteDB(String JavaDoc dbName)
1425        throws Exception JavaDoc
1426    {
1427
1428        // Get the full path.
1429
String JavaDoc deletePath = (new
1430            File JavaDoc(dbPath + separator + dbName)).getAbsolutePath();
1431
1432        // Have to shut it down before we can delete it.
1433
try {
1434            Connection JavaDoc conn =
1435                DriverManager.getConnection("jdbc:derby:" +
1436                    deletePath + ";shutdown=true");
1437            conn.close();
1438        } catch (SQLException JavaDoc se) {
1439        // shutdown exception.
1440
}
1441
1442        File JavaDoc f = new File JavaDoc(deletePath);
1443        if (!f.exists())
1444        // nothing to do.
1445
return;
1446
1447        File JavaDoc [] files = f.listFiles();
1448        for (int i = 0; i < files.length; i++)
1449            deleteFile(files[i]);
1450
1451        if (!f.delete()) {
1452        // still failed.
1453
System.out.println("ERROR: deleting: " +
1454                f.getName());
1455        }
1456
1457        // And finally, delete the CSJARS directory,
1458
// if there is one.
1459
deleteFile(new File JavaDoc(System.getProperty("user.dir") +
1460            separator + "CSJARS"));
1461
1462        System.out.println("Database '" + dbName + "' deleted.");
1463        return;
1464
1465    }
1466
1467    /* **********************************************
1468     * deleteFile:
1469     * Delete everything in a given directory, then
1470     * delete the directory itself (recursive).
1471     * @param aFile File object representing the directory
1472     * to be deleted.
1473     * @return the directory corresponding to aFile
1474     * has been deleted, as have all of its contents.
1475     ****/

1476
1477    private void deleteFile(File JavaDoc aFile)
1478        throws Exception JavaDoc
1479    {
1480
1481        if (!aFile.exists())
1482        // don't bother.
1483
return;
1484
1485        if (aFile.delete())
1486        // just a file; we're done.
1487
return;
1488
1489        // Otherwise, have to descend and delete all
1490
// files in this directory.
1491
File JavaDoc [] files = aFile.listFiles();
1492        if (files != null) {
1493            for (int i = 0; i < files.length; i++)
1494                deleteFile(files[i]);
1495        }
1496
1497        // Now try to delete.
1498
if (!aFile.delete()) {
1499        // still failed.
1500
System.out.println("ERROR: deleting: " +
1501                aFile.getName());
1502        }
1503
1504        return;
1505
1506    }
1507
1508    /* **********************************************
1509     * dumpFileToSysOut:
1510     * Checks to see if the received file is empty,
1511     * and prints a message saying so.
1512     * @param fName Name of the file to be written to output.
1513     * @return The contents of the specified file have
1514     * been written to System.out.
1515     ****/

1516
1517    private void dumpFileToSysOut(String JavaDoc fName) {
1518
1519        try {
1520
1521            BufferedReader JavaDoc dumpFile =
1522                new BufferedReader JavaDoc(new FileReader JavaDoc(fName));
1523
1524            String JavaDoc line = dumpFile.readLine();
1525            if (line != null) {
1526                System.out.println("File " + fName + " was NOT " +
1527                    "empty. Contents are:\n" +
1528                    "############## Begin File Contents ################\n");
1529                do {
1530                    System.out.println(line);
1531                    line = dumpFile.readLine();
1532                } while (line != null);
1533                System.out.println(
1534                    "############## End File Contents ################");
1535            }
1536            else
1537                System.out.println("File " + fName + " was empty.");
1538
1539            // Close the file.
1540
dumpFile.close();
1541
1542        } catch (Exception JavaDoc e) {
1543            System.out.println("FAILED: to dump file '" + fName + "'");
1544            e.printStackTrace(System.out);
1545        }
1546
1547        return;
1548
1549    }
1550
1551    /* **********************************************
1552     * isSystemGenerated:
1553     * Returns true if the received string looks like
1554     * it is a system-generated string. We assume
1555     * it's system-generated if either 1) it starts
1556     * with the letters "SQL", in which case it's a
1557     * system-name, or 2) it has a dash in it, in which
1558     * case it's a system id.
1559     * @param str The string to check.
1560     * @return True if we assume the string is system-
1561     * generated, false otherwise.
1562     ****/

1563
1564    private boolean isSystemGenerated(String JavaDoc str) {
1565
1566        return (looksLikeSysGenName(str) ||
1567            looksLikeSysGenId(str));
1568
1569    }
1570
1571    /* **********************************************
1572     * looksLikeSysGenName:
1573     * See if the received string looks like it is
1574     * a system-generated name. There are two types
1575     * of system-generated names: 1) visible names,
1576     * which start with "SQL", and 2) hidden names,
1577     * which exist for Stored Statements that are
1578     * used to back triggers; these names start with
1579     * "TRIGGERACTN_" and then have a UUID.
1580     * NOTE: This test assumes that none of object names
1581     * provided in "dblook_makeDB.sql" satisfy
1582     * either of these conditions. If they do, they
1583     * will be filtered out of the test output.
1584     * @param val The string value in question.
1585     * @return True if the value looks like it is a system-
1586     * generated name; false otherwise.
1587     ****/

1588
1589    private boolean looksLikeSysGenName(String JavaDoc val) {
1590
1591        return ((val != null) &&
1592            ((val.trim().indexOf("SQL") == 0) || // case 1.
1593
((val.trim().indexOf("TRIGGERACTN_") == 0) && // case 2.
1594
(val.indexOf("-") != -1))));
1595
1596    }
1597
1598    /* **********************************************
1599     * looksLikeSysGenId:
1600     * See if the received string looks like it is
1601     * a system-generated id (i.e. contains a dash (-)).
1602     * NOTE: This test assumes that none of object names
1603     * provided in "dblook_makeDB.sql" will contain
1604     * dashes. If they do, then they will be filtered out
1605     * in the test output.
1606     * @param val The string value in question.
1607     * @return True if the value looks like it is a system-
1608     * generated id; false otherwise.
1609     ****/

1610
1611    private boolean looksLikeSysGenId(String JavaDoc val) {
1612
1613        return ((val != null) && (val.indexOf("-") != -1));
1614
1615    }
1616
1617    /* **********************************************
1618     * columnHoldsObjectName:
1619     * Return true if the received column, which is from
1620     * some system table, holds the _name_ of a database
1621     * object (table, constraint, etc.). Typically, we
1622     * can just look for the keyword "NAME"; the exception
1623     * is aliases, where the name is held in a column called
1624     * ALIAS.
1625     * @param colName Name of the column in question.
1626     * @return True if the column name indicates that it
1627     * holds the _name_ of a database object; false if the
1628     * column name indicates that it holds something else.
1629     ****/

1630
1631    private boolean columnHoldsObjectName(String JavaDoc colName) {
1632
1633        return (colName.equals("ALIAS") ||
1634                (colName.indexOf("NAME") != -1));
1635
1636    }
1637
1638    /* **********************************************
1639     * printAsHeader:
1640     * Print the received string to output as a
1641     * header.
1642     * @param str String to print.
1643     ****/

1644
1645    private void printAsHeader(String JavaDoc str) {
1646
1647        writeOut("--\n*******************************************");
1648        writeOut(str);
1649        writeOut("*******************************************\n");
1650        return;
1651
1652    }
1653
1654}
1655
Popular Tags