Source Code Cross Referenced for dblook.java in  » Database-DBMS » db-derby-10.2 » org » apache » derby » 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.derby.tools 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:
0003:           Derby - Class org.apache.derby.tools.dblook
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.derby.tools;
0023:
0024:        import java.io.BufferedReader;
0025:        import java.io.StringReader;
0026:
0027:        import java.sql.DriverManager;
0028:        import java.sql.ResultSet;
0029:        import java.sql.Connection;
0030:        import java.sql.Statement;
0031:        import java.sql.PreparedStatement;
0032:        import java.sql.SQLException;
0033:        import java.sql.SQLWarning;
0034:        import java.sql.Timestamp;
0035:
0036:        import java.util.HashMap;
0037:        import java.util.StringTokenizer;
0038:        import java.util.ArrayList;
0039:
0040:        import org.apache.derby.iapi.tools.i18n.LocalizedResource;
0041:
0042:        import org.apache.derby.impl.tools.dblook.DB_Check;
0043:        import org.apache.derby.impl.tools.dblook.DB_Index;
0044:        import org.apache.derby.impl.tools.dblook.DB_Jar;
0045:        import org.apache.derby.impl.tools.dblook.DB_Key;
0046:        import org.apache.derby.impl.tools.dblook.DB_Table;
0047:        import org.apache.derby.impl.tools.dblook.DB_Schema;
0048:        import org.apache.derby.impl.tools.dblook.DB_Alias;
0049:        import org.apache.derby.impl.tools.dblook.DB_Trigger;
0050:        import org.apache.derby.impl.tools.dblook.DB_View;
0051:        import org.apache.derby.impl.tools.dblook.DB_GrantRevoke;
0052:        import org.apache.derby.impl.tools.dblook.Logs;
0053:
0054:        public final class dblook {
0055:
0056:            // DB2 enforces a maximum of 30 tables to be specified as part of
0057:            // the table list.
0058:            private static final int DB2_MAX_NUMBER_OF_TABLES = 30;
0059:
0060:            private Connection conn;
0061:            private static PreparedStatement getColNameFromNumberQuery;
0062:
0063:            // Mappings from id to name for schemas and tables (for ease
0064:            // of reference).
0065:            private static HashMap schemaMap;
0066:            private static HashMap tableIdToNameMap;
0067:
0068:            // Command-line Parameters.
0069:            private static String sourceDBUrl;
0070:            private static String ddlFileName;
0071:            private static String stmtDelimiter;
0072:            private static boolean appendLogs;
0073:            private static ArrayList tableList;
0074:            private static String schemaParam;
0075:            private static String targetSchema;
0076:            private static boolean skipViews;
0077:            private static boolean verbose;
0078:            private static String sourceDBName;
0079:
0080:            private static String lookLogName = "dblook.log";
0081:
0082:            private static LocalizedResource langUtil;
0083:
0084:            private static boolean sqlAuthorization;
0085:
0086:            /* ************************************************
0087:             * main:
0088:             * Initialize program state by creating a dblook object,
0089:             * and then start the DDL generation by calling "go".
0090:             * ****/
0091:
0092:            public static void main(String[] args) {
0093:
0094:                try {
0095:                    new dblook(args);
0096:                } catch (Exception e) {
0097:                    // All "normal" errors are logged and printed to
0098:                    // console according to command line arguments,
0099:                    // so if we get here, something unexpected must
0100:                    // have happened; print to error stream.
0101:                    e.printStackTrace();
0102:                }
0103:
0104:            }
0105:
0106:            /* ************************************************
0107:             * Constructor:
0108:             * Parse the command line, initialize logs, echo program variables,
0109:             * and load the Derby driver.
0110:             * @param args Array of dblook command-line arguments.
0111:             * ****/
0112:
0113:            public dblook(String[] args) throws Exception {
0114:
0115:                // Adjust the application in accordance with derby.ui.locale
0116:                // and derby.ui.codeset
0117:                langUtil = LocalizedResource.getInstance();
0118:
0119:                // Initialize class variables.
0120:                initState();
0121:
0122:                // Parse the command line.
0123:                if (!parseArgs(args)) {
0124:                    System.out.println(lookupMessage("DBLOOK_Usage"));
0125:                    return;
0126:                }
0127:
0128:                showVariables();
0129:
0130:                if (!loadDriver()) {
0131:                    // Failed when loading the driver.  We already logged
0132:                    // the exception, so just return.
0133:                    return;
0134:                }
0135:
0136:                schemaMap = new HashMap();
0137:                tableIdToNameMap = new HashMap();
0138:
0139:                // Now run the utility.
0140:                go();
0141:
0142:            }
0143:
0144:            /* ************************************************
0145:             * initState:
0146:             * Initialize class variables.
0147:             ****/
0148:
0149:            private void initState() {
0150:
0151:                sourceDBUrl = null;
0152:                ddlFileName = null;
0153:                stmtDelimiter = null;
0154:                appendLogs = false;
0155:                tableList = null;
0156:                targetSchema = null;
0157:                schemaParam = null;
0158:                skipViews = false;
0159:                verbose = false;
0160:                sourceDBName = null;
0161:                return;
0162:
0163:            }
0164:
0165:            /* ************************************************
0166:             * parseArgs:
0167:             * Parse the command-line arguments.
0168:             * @param args args[0] is the url for the source database.
0169:             * @return true if all parameters were loaded and the output
0170:             *  files were successfully created; false otherwise.
0171:             ****/
0172:
0173:            private boolean parseArgs(String[] args) {
0174:
0175:                if (args.length < 2)
0176:                    // must have minimum of 2 args: "-d" and "<dbUrl>".
0177:                    return false;
0178:
0179:                int st = 0;
0180:                for (int i = 0; i < args.length; i++) {
0181:                    st = loadParam(args, i);
0182:                    if (st == -1)
0183:                        return false;
0184:                    i = st;
0185:                }
0186:
0187:                if (sourceDBUrl == null) {
0188:                    // must have at least a database url.
0189:                    return false;
0190:                }
0191:
0192:                // At this point, all parameters should have been read into
0193:                // their respective class variables.  Use those
0194:                // variables for some further processing.
0195:
0196:                // Setup logs.
0197:                boolean okay = Logs.initLogs(lookLogName, ddlFileName,
0198:                        appendLogs, verbose, (stmtDelimiter == null ? ";"
0199:                                : stmtDelimiter));
0200:
0201:                // Get database name.
0202:                sourceDBName = extractDBNameFromUrl(sourceDBUrl);
0203:
0204:                // Set up schema restriction.
0205:                if ((schemaParam != null) && (schemaParam.length() > 0)
0206:                        && (schemaParam.charAt(0) != '"'))
0207:                // not quoted, so upper case, then add quotes.
0208:                {
0209:                    targetSchema = addQuotes(expandDoubleQuotes(schemaParam
0210:                            .toUpperCase(java.util.Locale.ENGLISH)));
0211:                } else
0212:                    targetSchema = addQuotes(expandDoubleQuotes(stripQuotes(schemaParam)));
0213:                return okay;
0214:
0215:            }
0216:
0217:            /* ************************************************
0218:             * loadParam:
0219:             * Read in a flag and its corresponding values from
0220:             * list of command line arguments, starting at
0221:             * the start'th argument.
0222:             * @return The position of the argument that was
0223:             *  most recently processed.
0224:             ****/
0225:
0226:            private int loadParam(String[] args, int start) {
0227:
0228:                if ((args[start].length() == 0) || args[start].charAt(0) != '-')
0229:                    // starting argument should be a flag; if it's
0230:                    // not, ignore it.
0231:                    return start;
0232:
0233:                boolean haveVal = (args.length > start + 1);
0234:                switch (args[start].charAt(1)) {
0235:
0236:                case 'd':
0237:                    if (!haveVal)
0238:                        return -1;
0239:                    if (args[start].length() == 2) {
0240:                        sourceDBUrl = stripQuotes(args[++start]);
0241:                        return start;
0242:                    }
0243:                    return -1;
0244:
0245:                case 'z':
0246:                    if (!haveVal)
0247:                        return -1;
0248:                    if (args[start].length() == 2) {
0249:                        schemaParam = args[++start];
0250:                        return start;
0251:                    }
0252:                    return -1;
0253:
0254:                case 't':
0255:                    if (!haveVal)
0256:                        return -1;
0257:                    if (args[start].equals("-td")) {
0258:                        stmtDelimiter = args[++start];
0259:                        return start;
0260:                    } else if (args[start].equals("-t"))
0261:                        // list of tables.
0262:                        return extractTableNamesFromList(args, start + 1);
0263:                    return -1;
0264:
0265:                case 'o':
0266:                    if (!haveVal)
0267:                        return -1;
0268:                    if ((args[start].length() == 2)
0269:                            && (args[start + 1].length() > 0)) {
0270:                        ddlFileName = args[++start];
0271:                        return start;
0272:                    }
0273:                    return -1;
0274:
0275:                case 'a':
0276:                    if (args[start].equals("-append")) {
0277:                        appendLogs = true;
0278:                        return start;
0279:                    }
0280:                    return -1;
0281:
0282:                case 'n':
0283:                    if (args[start].equals("-noview")) {
0284:                        skipViews = true;
0285:                        return start;
0286:                    }
0287:                    return -1;
0288:
0289:                case 'v':
0290:                    if (args[start].equals("-verbose")) {
0291:                        verbose = true;
0292:                        return start;
0293:                    }
0294:                    return -1;
0295:
0296:                default:
0297:                    return -1;
0298:
0299:                }
0300:
0301:            }
0302:
0303:            /* ************************************************
0304:             * loadDriver:
0305:             * Load derby driver.
0306:             * @param precondition sourceDBUrl has been loaded.
0307:             * @return false if anything goes wrong; true otherwise.
0308:             ****/
0309:
0310:            private boolean loadDriver() {
0311:
0312:                String derbyDriver = System.getProperty("driver");
0313:                if (derbyDriver == null) {
0314:                    if (sourceDBUrl.indexOf(":net://") != -1)
0315:                        derbyDriver = "com.ibm.db2.jcc.DB2Driver";
0316:                    else if (sourceDBUrl.startsWith("jdbc:derby://"))
0317:                        derbyDriver = "org.apache.derby.jdbc.ClientDriver";
0318:                    else
0319:                        derbyDriver = "org.apache.derby.jdbc.EmbeddedDriver";
0320:                }
0321:
0322:                try {
0323:                    Class.forName(derbyDriver).newInstance();
0324:                } catch (Exception e) {
0325:                    Logs.debug(e);
0326:                    return false;
0327:                }
0328:
0329:                return true;
0330:            }
0331:
0332:            /* ************************************************
0333:             * extractDBNameFromUrl:
0334:             * Given a database url, parse out the actual name
0335:             * of the database.  This is required for creation
0336:             * the DB2JJARS directory (the database name is part
0337:             * of the path to the jar).
0338:             * @param dbUrl The database url from which to extract the
0339:             *  the database name.
0340:             * @return the name of the database (including its
0341:             *  path, if provided) that is referenced by the url.
0342:             ****/
0343:
0344:            private String extractDBNameFromUrl(String dbUrl) {
0345:
0346:                if (dbUrl == null)
0347:                    // shouldn't happen; ignore it here, as an error
0348:                    // will be thrown we try to connect.
0349:                    return "";
0350:
0351:                int start = dbUrl.indexOf("jdbc:derby:");
0352:                if (start == -1)
0353:                    // not a valid url; just ignore it (an error
0354:                    // will be thrown when we try to connect).
0355:                    return "";
0356:
0357:                start = dbUrl.indexOf("://");
0358:                if (start == -1)
0359:                    // standard url (jdbc:derby:<dbname>).  Database
0360:                    // name starts right after "derby:".  The "6" in
0361:                    // the following line is the length of "derby:".
0362:                    start = dbUrl.indexOf("derby:") + 6;
0363:                else
0364:                    // Network Server url.  Database name starts right
0365:                    // after next slash (":net://hostname:port/<dbname>).
0366:                    // The "3" in the following line is the length of
0367:                    // "://".
0368:                    start = dbUrl.indexOf("/", start + 3) + 1;
0369:
0370:                int stop = -1;
0371:                if (dbUrl.charAt(start) == '"') {
0372:                    // database name is quoted; end of the name is the
0373:                    // closing quote.
0374:                    start++;
0375:                    stop = dbUrl.indexOf("\"", start);
0376:                } else {
0377:                    // Database name ends with the start of a list of connection	
0378:                    // attributes.  This list can begin with either a colon
0379:                    // or a semi-colon.
0380:                    stop = dbUrl.indexOf(":", start);
0381:                    if (stop != -1) {
0382:                        if ((dbUrl.charAt(stop + 1) == '/')
0383:                                || (dbUrl.charAt(stop + 1) == '\\'))
0384:                            // then this colon is part of the path (ex. "C:"),
0385:                            // so ignore it.
0386:                            stop = dbUrl.indexOf(":", stop + 2);
0387:                    }
0388:                    int stop2 = dbUrl.length();
0389:                    if (stop == -1)
0390:                        // no colons; see if we can find a semi-colon.
0391:                        stop = dbUrl.indexOf(";", start);
0392:                    else
0393:                        stop2 = dbUrl.indexOf(";", start);
0394:                    stop = (stop <= stop2 ? stop : stop2);
0395:                }
0396:
0397:                if (stop == -1)
0398:                    // we have a url that ends with database name (no
0399:                    // other attributes appended).
0400:                    stop = dbUrl.length();
0401:
0402:                return dbUrl.substring(start, stop);
0403:
0404:            }
0405:
0406:            /* ************************************************
0407:             * extractTableNamesFromList:
0408:             * Given an array of command line arguments containing
0409:             * a list of table names beginning at start'th position,
0410:             * read the list of table names and store them as
0411:             * our target table list.  Names without quotes are
0412:             * turned into ALL CAPS and then double quotes are
0413:             * added; names whcih already have double quotes are
0414:             * stored exactly as they are. NOTE: DB2 enforces
0415:             * maximum of 30 tables, and ignores the rest; so
0416:             * do we.
0417:             * @param args Array of command line arguments.
0418:             * @start Position of the start of the list of tables
0419:             *  with the args array.
0420:             * @return The position of the last table name in
0421:             *  the list of table names.
0422:             ****/
0423:
0424:            private int extractTableNamesFromList(String[] args, int start) {
0425:
0426:                int argIndex = start;
0427:                int count = 0;
0428:                tableList = new ArrayList();
0429:                while (argIndex < args.length) {
0430:
0431:                    if (((args[argIndex].length() > 0) && (args[argIndex]
0432:                            .charAt(0) == '-'))
0433:                            || (++count > DB2_MAX_NUMBER_OF_TABLES))
0434:                        // we're done with the table list.
0435:                        break;
0436:
0437:                    if ((args[argIndex].length() > 0)
0438:                            && (args[argIndex].charAt(0) == '"'))
0439:                        // it's quoted.
0440:                        tableList
0441:                                .add(addQuotes(expandDoubleQuotes(stripQuotes(args[argIndex++]))));
0442:                    else
0443:                        // not quoted, so make it all caps, then add
0444:                        // quotes.
0445:                        tableList
0446:                                .add(addQuotes(expandDoubleQuotes(args[argIndex++]
0447:                                        .toUpperCase(java.util.Locale.ENGLISH))));
0448:
0449:                }
0450:
0451:                if (tableList.size() == 0)
0452:                    tableList = null;
0453:
0454:                return argIndex - 1;
0455:
0456:            }
0457:
0458:            /* ************************************************
0459:             * showVariables:
0460:             * Echo primary variables to output, so user can see
0461:             * what s/he specified.
0462:             ****/
0463:
0464:            private void showVariables() {
0465:
0466:                if (ddlFileName != null) {
0467:                    Logs.reportString("============================\n");
0468:                    Logs.reportMessage("DBLOOK_FileCreation");
0469:                    if (verbose)
0470:                        writeVerboseOutput("DBLOOK_OutputLocation", ddlFileName);
0471:                }
0472:
0473:                Logs.reportMessage("DBLOOK_Timestamp", new Timestamp(System
0474:                        .currentTimeMillis()).toString());
0475:                Logs.reportMessage("DBLOOK_DBName", sourceDBName);
0476:                Logs.reportMessage("DBLOOK_DBUrl", sourceDBUrl);
0477:                if (tableList != null)
0478:                    Logs.reportMessage("DBLOOK_TargetTables");
0479:                if (schemaParam != null)
0480:                    Logs.reportMessage("DBLOOK_TargetSchema",
0481:                            stripQuotes(schemaParam));
0482:                Logs.reportString("appendLogs: " + appendLogs + "\n");
0483:                return;
0484:
0485:            }
0486:
0487:            /* ************************************************
0488:             * go:
0489:             * Connect to the source database, prepare statements,
0490:             * and load a list of table id-to-name mappings.  Then,
0491:             * generate the DDL for the various objects in the
0492:             * database by making calls to static methods of helper
0493:             * classes (one helper class for each type of database
0494:             * object).  If a particular object type should not be
0495:             * generated (because of the user-specified command-
0496:             * line), then we enforce that here.
0497:             * @precondition all user-specified parameters have
0498:             *  been loaded.
0499:             * @return DDL for the source database has been
0500:             *  generated and printed to output, subject to
0501:             *  user-specified restrictions.
0502:             * ****/
0503:
0504:            private void go() throws Exception {
0505:
0506:                try {
0507:                    // Connect to the database, prepare statements,
0508:                    // and load id-to-name mappings.
0509:                    this .conn = DriverManager.getConnection(sourceDBUrl);
0510:                    prepForDump();
0511:
0512:                    // Generate DDL.
0513:
0514:                    // Start with schemas, since we might need them to
0515:                    // exist for jars to load properly.
0516:                    DB_Schema.doSchemas(this .conn, (tableList != null)
0517:                            && (targetSchema == null));
0518:
0519:                    if (tableList == null) {
0520:                        // Don't do these if user just wants table-related objects.
0521:                        DB_Jar.doJars(sourceDBName, this .conn);
0522:                        DB_Alias.doProceduresAndFunctions(this .conn);
0523:                    }
0524:
0525:                    DB_Table.doTables(this .conn, tableIdToNameMap);
0526:                    DB_Index.doIndexes(this .conn);
0527:                    DB_Alias.doSynonyms(this .conn);
0528:                    DB_Key.doKeys(this .conn);
0529:                    DB_Check.doChecks(this .conn);
0530:
0531:                    if (!skipViews)
0532:                        DB_View.doViews(this .conn);
0533:
0534:                    DB_Trigger.doTriggers(this .conn);
0535:
0536:                    DB_GrantRevoke.doAuthorizations(this .conn);
0537:
0538:                    // That's it; we're done.
0539:                    if (getColNameFromNumberQuery != null)
0540:                        getColNameFromNumberQuery.close();
0541:                    Logs.cleanup();
0542:
0543:                } catch (SQLException sqlE) {
0544:                    Logs.debug(sqlE);
0545:                    Logs.debug(Logs.unRollExceptions(sqlE), (String) null);
0546:                    Logs.cleanup();
0547:                    return;
0548:                } catch (Exception e) {
0549:                    Logs.debug(e);
0550:                    Logs.cleanup();
0551:                    return;
0552:                } finally {
0553:                    // Close our connection.
0554:                    if (conn != null) {
0555:                        conn.commit();
0556:                        conn.close();
0557:                    }
0558:                }
0559:
0560:            }
0561:
0562:            /* ************************************************
0563:             * prepForDump:
0564:             * Prepare any useful statements (i.e. statements that
0565:             * are required by more than one helper class) and load
0566:             * the id-to-name mappings for the source database.
0567:             ****/
0568:
0569:            private void prepForDump() throws Exception {
0570:
0571:                // We're only SELECTing throughout all of this, so no need
0572:                // to commit (plus, disabling commit makes it easier to
0573:                // have multiple ResultSets open on the same connection).
0574:                this .conn.setAutoCommit(false);
0575:
0576:                // Prepare statements.
0577:                getColNameFromNumberQuery = conn
0578:                        .prepareStatement("SELECT COLUMNNAME FROM SYS.SYSCOLUMNS WHERE "
0579:                                + "REFERENCEID = ? AND COLUMNNUMBER = ?");
0580:
0581:                // Load list of user tables and table ids, for general use.
0582:                Statement stmt = conn.createStatement();
0583:                ResultSet rs = stmt
0584:                        .executeQuery("SELECT T.TABLEID, T.TABLENAME, "
0585:                                + "S.SCHEMANAME FROM SYS.SYSTABLES T, SYS.SYSSCHEMAS S "
0586:                                + "WHERE T.TABLETYPE = 'T' AND T.SCHEMAID = S.SCHEMAID");
0587:
0588:                while (rs.next()) {
0589:                    String tableName = addQuotes(expandDoubleQuotes(rs
0590:                            .getString(2)));
0591:                    String schemaName = addQuotes(expandDoubleQuotes(rs
0592:                            .getString(3)));
0593:                    tableIdToNameMap.put(rs.getString(1), schemaName + "."
0594:                            + tableName);
0595:                }
0596:
0597:                // Load schema id's and names.
0598:                rs = stmt.executeQuery("SELECT SCHEMAID, SCHEMANAME FROM "
0599:                        + "SYS.SYSSCHEMAS");
0600:                while (rs.next()) {
0601:                    schemaMap.put(rs.getString(1),
0602:                            addQuotes(expandDoubleQuotes(rs.getString(2))));
0603:                }
0604:
0605:                // Check if sqlAuthorization mode is on. If so, need to generate
0606:                // authorization statements.
0607:                rs = stmt
0608:                        .executeQuery("VALUES SYSCS_UTIL.SYSCS_GET_DATABASE_PROPERTY"
0609:                                + "('derby.database.sqlAuthorization')");
0610:                if (rs.next()) {
0611:                    String sqlAuth = rs.getString(1);
0612:                    if (Boolean.valueOf(sqlAuth).booleanValue())
0613:                        sqlAuthorization = true;
0614:                }
0615:                stmt.close();
0616:
0617:                // Load default property values.
0618:                return;
0619:
0620:            }
0621:
0622:            /* ************************************************
0623:             * getColumnListFromDescription:
0624:             * Takes string description of column numbers in the
0625:             * form of "(2, 1, 3...)" and the id of the table
0626:             * having those columns, and then returns a string
0627:             * with the column numbers replaced by their actual
0628:             * names ('2' is replaced with the 2nd column in the
0629:             * table, '1' with the first column, etc.).
0630:             * @param tableId the id of the table to which the column
0631:             *   numbers should be applied.
0632:             * @param description a string holding a list of column
0633:             *  numbers, enclosed in parentheses and separated
0634:             *  by commas.
0635:             * @return a new string with the column numbers in
0636:             *  'description' replaced by their column names;
0637:             *  also, the parentheses have been stripped off.
0638:             ****/
0639:
0640:            public static String getColumnListFromDescription(String tableId,
0641:                    String description) throws SQLException {
0642:
0643:                StringBuffer sb = new StringBuffer();
0644:                StringTokenizer tokenizer = new StringTokenizer(description
0645:                        .substring(description.indexOf("(") + 1, description
0646:                                .lastIndexOf(")")), " ,", true);
0647:
0648:                boolean firstCol = true;
0649:                while (tokenizer.hasMoreTokens()) {
0650:
0651:                    String tok = tokenizer.nextToken().trim();
0652:                    if (tok.equals(""))
0653:                        continue;
0654:                    else if (tok.equals(",")) {
0655:                        firstCol = false;
0656:                        continue;
0657:                    }
0658:                    try {
0659:                        String colName = getColNameFromNumber(tableId, (Integer
0660:                                .valueOf(tok)).intValue());
0661:                        if (!firstCol)
0662:                            sb.append(", ");
0663:                        sb.append(colName);
0664:                    } catch (NumberFormatException e) {
0665:                        // not a number; could be "ASC" or "DESC" tag,
0666:                        // which is okay; otherwise, something's wrong.
0667:                        tok = tok.toUpperCase();
0668:                        if (tok.equals("DESC") || tok.equals("ASC"))
0669:                            // then this is okay; just add the token to result.
0670:                            sb.append(" " + tok);
0671:                        else
0672:                            // shouldn't happen.
0673:                            Logs.debug("INTERNAL ERROR: read a non-number ("
0674:                                    + tok
0675:                                    + ") when a column number was expected:\n"
0676:                                    + description, (String) null);
0677:                    }
0678:
0679:                }
0680:
0681:                return sb.toString();
0682:
0683:            }
0684:
0685:            /* ************************************************
0686:             * getColNameFromNumber:
0687:             * Takes a tableid and a column number colNum, and
0688:             * returns the name of the colNum'th column in the
0689:             * table with tableid.
0690:             * @param tableid id of the table.
0691:             * @param colNum number of the column for which we want
0692:             *  the name.
0693:             * @return The name of the colNum'th column in the
0694:             *  table with tableid.
0695:             ****/
0696:
0697:            public static String getColNameFromNumber(String tableId, int colNum)
0698:                    throws SQLException {
0699:
0700:                getColNameFromNumberQuery.setString(1, tableId);
0701:                getColNameFromNumberQuery.setInt(2, colNum);
0702:                ResultSet rs = getColNameFromNumberQuery.executeQuery();
0703:
0704:                if (!rs.next()) {
0705:                    // shouldn't happen.
0706:                    Logs.debug("INTERNAL ERROR: Failed column number "
0707:                            + "lookup for table " + lookupTableId(tableId)
0708:                            + ", column " + colNum, (String) null);
0709:                    rs.close();
0710:                    return "";
0711:                } else {
0712:                    String colName = addQuotes(expandDoubleQuotes(rs
0713:                            .getString(1)));
0714:                    rs.close();
0715:                    return colName;
0716:                }
0717:
0718:            }
0719:
0720:            /* ************************************************
0721:             * addQuotes:
0722:             * Add quotes to the received object name, and return
0723:             * the result.
0724:             * @param name the name to which to add quotes.
0725:             * @return the name with double quotes around it.
0726:             ****/
0727:
0728:            public static String addQuotes(String name) {
0729:
0730:                if (name == null)
0731:                    return null;
0732:
0733:                return "\"" + name + "\"";
0734:
0735:            }
0736:
0737:            public static String addSingleQuotes(String name) {
0738:
0739:                if (name == null)
0740:                    return null;
0741:
0742:                return "'" + name + "'";
0743:            }
0744:
0745:            /* ************************************************
0746:             * stripQuotes:
0747:             * Takes a name and, if the name is enclosed in
0748:             * quotes, strips the quotes off.  This method
0749:             * assumes that the received String either has no quotes,
0750:             * or has a quote (double or single) as the very first
0751:             * AND very last character.
0752:             * @param quotedName a name with quotes as the first
0753:             *  and last character, or else with no quotes at all.
0754:             * @return quotedName, without the quotes.
0755:             ****/
0756:
0757:            public static String stripQuotes(String quotedName) {
0758:
0759:                if (quotedName == null)
0760:                    return null;
0761:
0762:                if (!(quotedName.startsWith("'") || quotedName.startsWith("\"")))
0763:                    // name doesn't _start_ with a quote, so we do nothing.
0764:                    return quotedName;
0765:
0766:                if (!(quotedName.endsWith("'") || quotedName.endsWith("\"")))
0767:                    // name doesn't _end_ with a quote, so we do nothing.
0768:                    return quotedName;
0769:
0770:                // Remove starting and ending quotes.
0771:                return quotedName.substring(1, quotedName.length() - 1);
0772:
0773:            }
0774:
0775:            /* ************************************************
0776:             * isExcludedTable:
0777:             * Takes a table name and determines whether or not
0778:             * the DDL for objects related to that table should be
0779:             * generated.
0780:             * @param tableName name of the table to check.
0781:             * @return true if 1) the user specified a table list
0782:             *  and that list does NOT include the received name; or
0783:             *  2) if the user specified a schema restriction and
0784:             *  the received name does NOT have that schema; false
0785:             *  otherwise.
0786:             ****/
0787:
0788:            public static boolean isExcludedTable(String tableName) {
0789:
0790:                if (tableName == null)
0791:                    return true;
0792:
0793:                int dot = tableName.indexOf(".");
0794:                if (dot != -1) {
0795:                    // strip off the schema part of the name, and see if we're
0796:                    // okay to use it.
0797:                    if (isIgnorableSchema(tableName.substring(0, dot)))
0798:                        // then we exclude this table.
0799:                        return true;
0800:                    tableName = tableName
0801:                            .substring(dot + 1, tableName.length());
0802:                }
0803:
0804:                return ((tableList != null) && !tableList.contains(tableName));
0805:
0806:            }
0807:
0808:            /* ************************************************
0809:             * Takes a schema name and determines whether or
0810:             * not the DDL for objects with that schema should
0811:             * be generated.
0812:             * @param schemaName schema name to be checked.
0813:             * @return true if 1) the user specified a target
0814:             *  schema and that target is NOT the same as the
0815:             *  received schema name, or 2) the schema is a
0816:             *  system schema (SYS, SYSVISUAL, or SYSIBM);
0817:             *  false otherwise;
0818:             ****/
0819:
0820:            private static final String[] ignorableSchemaNames = { "SYSIBM",
0821:                    "SYS", "SYSVISUAL", "SYSCAT", "SYSFUN", "SYSPROC",
0822:                    "SYSSTAT", "NULLID", "SYSCS_ADMIN", "SYSCS_DIAG",
0823:                    "SYSCS_UTIL", "SQLJ" };
0824:
0825:            public static boolean isIgnorableSchema(String schemaName) {
0826:
0827:                if ((targetSchema != null)
0828:                        && (!schemaName.equals(targetSchema)))
0829:                    return true;
0830:
0831:                schemaName = stripQuotes(schemaName);
0832:
0833:                boolean ret = false;
0834:
0835:                for (int i = ignorableSchemaNames.length - 1; i >= 0;) {
0836:                    if ((ret = ignorableSchemaNames[i--]
0837:                            .equalsIgnoreCase(schemaName)))
0838:                        break;
0839:                }
0840:
0841:                return (ret);
0842:            }
0843:
0844:            /* ************************************************
0845:             * Takes a string and determines whether or not that
0846:             * string makes reference to any of the table names
0847:             * in the user-specified table list.
0848:             * @param str The string in which to search for table names.
0849:             * @return true if 1) the user didn't specify a
0850:             *  target table list, or 2) the received string
0851:             *  contains at least one of the table names in the
0852:             *  user-specified target list; false otherwise.
0853:             ****/
0854:
0855:            public static boolean stringContainsTargetTable(String str) {
0856:
0857:                if (str == null)
0858:                    // if the string is null, it can't possibly contain
0859:                    // any table names.
0860:                    return false;
0861:
0862:                if (tableList == null)
0863:                    // if we have no target tables, then default to true.
0864:                    return true;
0865:
0866:                int strLen = str.length();
0867:                for (int i = 0; i < tableList.size(); i++) {
0868:
0869:                    String tableName = (String) tableList.get(i);
0870:                    tableName = expandDoubleQuotes(stripQuotes(tableName));
0871:                    int nameLen = tableName.length();
0872:                    String strCopy;
0873:                    if (tableName.equals(tableName
0874:                            .toUpperCase(java.util.Locale.ENGLISH)))
0875:                        // case doesn't matter.
0876:                        strCopy = str.toUpperCase();
0877:                    else
0878:                        strCopy = str;
0879:                    int pos = strCopy.indexOf(tableName);
0880:                    while (pos != -1) {
0881:
0882:                        // If we found it, make sure it's really a match.
0883:                        // First, see if it's part of another word.
0884:                        if (!partOfWord(str, pos, nameLen, strLen)) {
0885:
0886:                            // See if the match is in quotes--if so, then
0887:                            // it should match the table name's case.
0888:                            if ((pos >= 1) && (strCopy.charAt(pos - 1) == '"')
0889:                                    && (pos + nameLen < strCopy.length())
0890:                                    && (strCopy.charAt(pos + nameLen) == '"')) { // match is quoted; check it's case.
0891:                                if (str.substring(pos, pos + nameLen).equals(
0892:                                        tableName))
0893:                                    // everything checks out.
0894:                                    return true;
0895:                            } else
0896:                                // match isn't quoted, so we're okay as is.
0897:                                return true;
0898:                        }
0899:
0900:                        pos = str.indexOf(tableName, pos + nameLen);
0901:
0902:                    }
0903:                }
0904:
0905:                // If we get here, we didn't find it.
0906:                return false;
0907:
0908:            }
0909:
0910:            /* ************************************************
0911:             * partOfWord:
0912:             * Returns true if the part of the string given by
0913:             * str.substring(pos, pos + nameLen) is part of
0914:             * another word.
0915:             * @param str The string in which we're looking.
0916:             * @param pos The position at which the substring in
0917:             *  question begins.
0918:             * @param nameLen the length of the substring in
0919:             *  question.
0920:             * @param strLen The length of the string in which
0921:             *  we're looking.
0922:             * @return true if the substring from pos to
0923:             *  pos+nameLen is part of larger word (i.e.
0924:             *  if it has a letter/digit immediately before
0925:             *  or after); false otherwise.
0926:             ****/
0927:
0928:            private static boolean partOfWord(String str, int pos, int nameLen,
0929:                    int strLen) {
0930:
0931:                boolean somethingBefore = false;
0932:                if (pos > 0) {
0933:                    char c = str.charAt(pos - 1);
0934:                    somethingBefore = ((c == '_') || Character
0935:                            .isLetterOrDigit(c));
0936:                }
0937:
0938:                boolean somethingAfter = false;
0939:                if (pos + nameLen < strLen) {
0940:                    char c = str.charAt(pos + nameLen);
0941:                    somethingAfter = ((c == '_') || Character
0942:                            .isLetterOrDigit(c));
0943:                }
0944:
0945:                return (somethingBefore || somethingAfter);
0946:
0947:            }
0948:
0949:            /* ************************************************
0950:             * expandDoubleQuotes:
0951:             * If the received SQL id contains a quote, we have
0952:             * to expand it into TWO quotes so that it can be
0953:             * treated correctly at parse time.
0954:             * @param name Id that we want to print.
0955:             ****/
0956:
0957:            public static String expandDoubleQuotes(String name) {
0958:
0959:                if ((name == null) || (name.indexOf("\"") < 0))
0960:                    // nothing to do.
0961:                    return name;
0962:
0963:                char[] cA = name.toCharArray();
0964:
0965:                // Worst (and extremely unlikely) case is every 
0966:                // character is a double quote, which means the
0967:                // escaped string would need to be 2 times as long.
0968:                char[] result = new char[2 * cA.length];
0969:
0970:                int j = 0;
0971:                for (int i = 0; i < cA.length; i++) {
0972:
0973:                    if (cA[i] == '"') {
0974:                        result[j++] = '"';
0975:                        result[j++] = '"';
0976:                    } else
0977:                        result[j++] = cA[i];
0978:
0979:                }
0980:
0981:                return new String(result, 0, j);
0982:
0983:            }
0984:
0985:            /* ************************************************
0986:             * lookupSchemaId:
0987:             * Return the schema name corresponding to the
0988:             * received schema id.
0989:             * @param schemaId The id to look up.
0990:             * @return the schema name.
0991:             ****/
0992:
0993:            public static String lookupSchemaId(String schemaId) {
0994:
0995:                return (String) (schemaMap.get(schemaId));
0996:
0997:            }
0998:
0999:            /* ************************************************
1000:             * lookupTableId:
1001:             * Return the table name corresponding to the
1002:             * received table id.
1003:             * @param tableId The id to look up.
1004:             * @return the table name.
1005:             ****/
1006:
1007:            public static String lookupTableId(String tableId) {
1008:
1009:                return (String) (tableIdToNameMap.get(tableId));
1010:
1011:            }
1012:
1013:            /* ************************************************
1014:             * writeVerboseOutput:
1015:             * Writes the received string as "verbose" output,
1016:             * meaning that we write it to System.err.  We
1017:             * choose System.err so that the string doesn't
1018:             * show up if the user pipes dblook output to
1019:             * a file (unless s/he explicitly pipes System.err
1020:             * output to that file, as well).
1021:             * @param key Key for the message to be printed as
1022:             *  verbose output.
1023:             * @param value Value to be substituted into the
1024:             *  message.
1025:             * @return message for received key has been printed
1026:             *  to System.err.
1027:             ****/
1028:
1029:            public static void writeVerboseOutput(String key, String value) {
1030:
1031:                if (value == null)
1032:                    System.err.println(lookupMessage(key));
1033:                else
1034:                    System.err.println(lookupMessage(key,
1035:                            new String[] { value }));
1036:                return;
1037:
1038:            }
1039:
1040:            /* ************************************************
1041:             * lookupMessage:
1042:             * Retrieve a localized message.
1043:             * @param key The key for the localized message.
1044:             * @return the message corresponding to the received
1045:             *  key.
1046:             ****/
1047:
1048:            public static String lookupMessage(String key) {
1049:
1050:                return lookupMessage(key, null);
1051:
1052:            }
1053:
1054:            /* ************************************************
1055:             * lookupMessage:
1056:             * Retreive a localized message.
1057:             * @param key The key for the localized message.
1058:             * @param vals Array of values to be used in the
1059:             *   message.
1060:             * @return the message corresponding to the received
1061:             *  key, with the received values substituted where
1062:             *  appropriate.
1063:             ****/
1064:
1065:            public static String lookupMessage(String key, String[] vals) {
1066:
1067:                String msg = "";
1068:                if (vals == null)
1069:                    msg = langUtil.getTextMessage(key);
1070:                else {
1071:                    switch (vals.length) {
1072:                    case 1:
1073:                        msg = langUtil.getTextMessage(key, vals[0]);
1074:                        break;
1075:                    case 2:
1076:                        msg = langUtil.getTextMessage(key, vals[0], vals[1]);
1077:                        break;
1078:                    default: /* shouldn't happen */
1079:                        break;
1080:                    }
1081:                }
1082:
1083:                return msg;
1084:
1085:            }
1086:
1087:            /* ************************************************
1088:             * removeNewlines:
1089:             * Remove any newline characters from the received
1090:             * string (replace them with spaces).
1091:             * @param str The string from which we are removing
1092:             *  all newline characters.
1093:             * @return The string, with all newline characters
1094:             *  replaced with spaces.
1095:             ****/
1096:
1097:            public static String removeNewlines(String str) {
1098:
1099:                if (str == null)
1100:                    // don't do anything.
1101:                    return null;
1102:
1103:                StringBuffer result = null;
1104:                try {
1105:
1106:                    BufferedReader strVal = new BufferedReader(
1107:                            new StringReader(str));
1108:                    for (String txt = strVal.readLine(); txt != null; txt = strVal
1109:                            .readLine()) {
1110:                        if (result == null)
1111:                            result = new StringBuffer(txt);
1112:                        else {
1113:                            result.append(" ");
1114:                            result.append(txt);
1115:                        }
1116:                    }
1117:
1118:                    return result.toString();
1119:
1120:                } catch (Exception e) {
1121:                    // if something went wrong, just return the string as is--
1122:                    // worst case is that the generated DDL is correct, it just
1123:                    // can't be run in some SQL script apps (because of the newline
1124:                    // characters).
1125:                    return str;
1126:                }
1127:
1128:            }
1129:
1130:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.