Source Code Cross Referenced for TableDiffCommand.java in  » Database-Client » Henplus » henplus » plugins » tablediff » 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 Client » Henplus » henplus.plugins.tablediff 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * This is free software, licensed under the Gnu Public License (GPL)
003:         * get a copy from <http://www.gnu.org/licenses/gpl.html>
004:         * @version $Id: TableDiffCommand.java,v 1.10 2005/11/27 16:20:28 hzeller Exp $ 
005:         * @author <a href="mailto:martin.grotzke@javakaffee.de">Martin Grotzke</a>
006:         */
007:        package henplus.plugins.tablediff;
008:
009:        import henplus.AbstractCommand;
010:        import henplus.CommandDispatcher;
011:        import henplus.HenPlus;
012:        import henplus.SQLSession;
013:        import henplus.SessionManager;
014:        import henplus.commands.ListUserObjectsCommand;
015:        import henplus.sqlmodel.Column;
016:        import henplus.sqlmodel.Table;
017:        import henplus.view.util.NameCompleter;
018:
019:        import java.util.ArrayList;
020:        import java.util.HashSet;
021:        import java.util.Iterator;
022:        import java.util.List;
023:        import java.util.Set;
024:        import java.util.SortedSet;
025:        import java.util.StringTokenizer;
026:
027:        public final class TableDiffCommand extends AbstractCommand {
028:            protected static final String _command = "tablediff";
029:            protected static final String COMMAND_DELIMITER = ";";
030:            protected static final String OPTION_SINGLE_DB = "-singledb";
031:
032:            /**
033:             * 
034:             */
035:            public TableDiffCommand() {
036:            }
037:
038:            /* (non-Javadoc)
039:             * @see henplus.Command#getCommandList()
040:             */
041:            public String[] getCommandList() {
042:                return new String[] { _command };
043:            }
044:
045:            /* (non-Javadoc)
046:             * @see henplus.Command#participateInCommandCompletion()
047:             */
048:            public boolean participateInCommandCompletion() {
049:                return true;
050:            }
051:
052:            /* (non-Javadoc)
053:             * @see henplus.Command#execute(henplus.SQLSession, java.lang.String, java.lang.String)
054:             */
055:            public int execute(SQLSession session, String command,
056:                    String parameters) {
057:                // first set the option for case sensitive comparison of column names
058:                boolean colNameIgnoreCase = true;
059:                StringTokenizer st = new StringTokenizer(parameters);
060:
061:                // HenPlus.msg().println( "[execute] command: " + command + ", parameters: " + parameters );
062:
063:                int result = SUCCESS;
064:
065:                if (parameters.indexOf(OPTION_SINGLE_DB) != -1) {
066:
067:                    // required: session
068:                    if (session == null) {
069:                        HenPlus.msg().println(
070:                                "You need a valid session for this command.");
071:                        return EXEC_FAILED;
072:                    }
073:
074:                    // required: option, table1, table2
075:                    if (st.countTokens() != 3) {
076:                        return SYNTAX_ERROR;
077:                    }
078:
079:                    // push the tokenizer to skip the option
080:                    st.nextToken();
081:                    String table1 = st.nextToken();
082:                    String table2 = st.nextToken();
083:
084:                    try {
085:                        long start = System.currentTimeMillis();
086:
087:                        diffTable(session, table1, table2, colNameIgnoreCase);
088:
089:                        StringBuffer msg = new StringBuffer();
090:                        msg.append("Diffing ").append(" tables ")
091:                                .append(table1).append(" and ").append(table2)
092:                                .append(" took ").append(
093:                                        System.currentTimeMillis() - start)
094:                                .append(" ms.");
095:
096:                        HenPlus.msg().println(msg.toString());
097:
098:                    } catch (Exception e) {
099:                        e.printStackTrace();
100:                    }
101:
102:                } else {
103:                    result = executeDoubleDb(st, colNameIgnoreCase);
104:                }
105:
106:                return result;
107:            }
108:
109:            private int executeDoubleDb(StringTokenizer st,
110:                    boolean colNameIgnoreCase) {
111:                if (st.countTokens() < 3) {
112:                    return SYNTAX_ERROR;
113:                }
114:
115:                SessionManager sessionManager = HenPlus.getInstance()
116:                        .getSessionManager();
117:
118:                if (sessionManager.getSessionCount() < 2) {
119:                    System.err
120:                            .println("You need two valid sessions for this command.");
121:                    return SYNTAX_ERROR;
122:                }
123:
124:                SQLSession first = sessionManager.getSessionByName(st
125:                        .nextToken());
126:                SQLSession second = sessionManager.getSessionByName(st
127:                        .nextToken());
128:
129:                if (first == null || second == null) {
130:                    HenPlus.msg().println(
131:                            "You need two valid sessions for this command.");
132:                    return EXEC_FAILED;
133:                } else if (first == second) {
134:                    HenPlus
135:                            .msg()
136:                            .println(
137:                                    "You should specify two different sessions for this command.");
138:                    return EXEC_FAILED;
139:                } else if (!st.hasMoreTokens()) {
140:                    HenPlus.msg().println(
141:                            "You should specify at least one table.");
142:                    return EXEC_FAILED;
143:                }
144:
145:                try {
146:                    long start = System.currentTimeMillis();
147:                    int count = 0;
148:
149:                    ListUserObjectsCommand objectLister = HenPlus.getInstance()
150:                            .getObjectLister();
151:                    SortedSet tablesOne = objectLister
152:                            .getTableNamesForSession(first);
153:                    SortedSet tablesTwo = objectLister
154:                            .getTableNamesForSession(second);
155:
156:                    Set alreadyDiffed = new HashSet(); // which tables got already diffed?
157:
158:                    /*
159:                     * which tables are found in the first session via wildcards but are not contained
160:                     * in the second session?
161:                     */
162:                    ArrayList missedFromWildcards = new ArrayList();
163:
164:                    while (st.hasMoreTokens()) {
165:
166:                        String nextToken = st.nextToken();
167:
168:                        if ("*".equals(nextToken)
169:                                || nextToken.indexOf('*') > -1) {
170:                            Iterator iter = null;
171:
172:                            if ("*".equals(nextToken))
173:                                iter = objectLister
174:                                        .getTableNamesIteratorForSession(first);
175:                            else if (nextToken.indexOf('*') > -1) {
176:                                String tablePrefix = nextToken.substring(0,
177:                                        nextToken.length() - 1);
178:                                NameCompleter compl = new NameCompleter(
179:                                        tablesOne);
180:                                iter = compl.getAlternatives(tablePrefix);
181:                            }
182:
183:                            while (iter.hasNext()) {
184:                                Object objTableName = iter.next();
185:                                count = diffConditionally(objTableName,
186:                                        colNameIgnoreCase, first, second,
187:                                        tablesTwo, alreadyDiffed,
188:                                        missedFromWildcards, count);
189:                            }
190:                        } else if (!alreadyDiffed.contains(nextToken)) {
191:                            diffTable(first, second, nextToken,
192:                                    colNameIgnoreCase);
193:                            alreadyDiffed.add(nextToken);
194:                            count++;
195:                        }
196:
197:                    }
198:
199:                    StringBuffer msg = new StringBuffer();
200:                    msg.append("Diffing ").append(count).append(
201:                            (count == 1) ? " table took " : " tables took ")
202:                            .append(System.currentTimeMillis() - start).append(
203:                                    " ms.");
204:
205:                    // if there were tables found via wildcards but not contained in both sessions then let
206:                    // the user know this.
207:                    if (missedFromWildcards.size() > 0) {
208:                        msg
209:                                .append("\nTables which matched a given wildcard in your first\n"
210:                                        + "session but were not found in your second session:\n");
211:                        Iterator iter = missedFromWildcards.iterator();
212:                        while (iter.hasNext()) {
213:                            msg.append(iter.next()).append(", ");
214:                        }
215:                        // remove the last two chars
216:                        msg.delete(msg.length() - 2, msg.length());
217:                    }
218:
219:                    HenPlus.msg().println(msg.toString());
220:
221:                } catch (Exception e) {
222:                    e.printStackTrace();
223:                }
224:
225:                return SUCCESS;
226:            }
227:
228:            private int diffConditionally(Object objTableName,
229:                    boolean colNameIgnoreCase, SQLSession first,
230:                    SQLSession second, SortedSet tablesTwo, Set alreadyDiffed,
231:                    List missedFromWildcards, int count) {
232:                if (tablesTwo.contains(objTableName)) {
233:                    if (!alreadyDiffed.contains(objTableName)) {
234:                        String tableName = (String) objTableName;
235:                        diffTable(first, second, tableName, colNameIgnoreCase);
236:                        alreadyDiffed.add(objTableName);
237:                        count++;
238:                    }
239:                } else {
240:                    missedFromWildcards.add(objTableName);
241:                }
242:                return count;
243:            }
244:
245:            private void diffTable(SQLSession first, SQLSession second,
246:                    String tableName, boolean colNameIgnoreCase) {
247:                Table ref = first.getTable(tableName);
248:                Table diff = second.getTable(tableName);
249:                TableDiffResult diffResult = TableDiffer.diffTables(ref, diff,
250:                        colNameIgnoreCase);
251:                if (diffResult == null) {
252:                    HenPlus.msg().println("No diff for table " + tableName);
253:                } else {
254:                    HenPlus.msg().println(
255:                            "Diff result for table " + tableName + ":");
256:                    ResultTablePrinter.printResult(diffResult);
257:                }
258:            }
259:
260:            private void diffTable(SQLSession session, String tableName1,
261:                    String tableName2, boolean colNameIgnoreCase) {
262:                Table ref = session.getTable(tableName1);
263:                Table diff = session.getTable(tableName2);
264:                TableDiffResult diffResult = TableDiffer.diffTables(ref, diff,
265:                        colNameIgnoreCase);
266:                if (diffResult == null) {
267:                    HenPlus.msg().println(
268:                            "No diff for tables " + tableName1 + " and "
269:                                    + tableName2 + ".");
270:                } else {
271:                    HenPlus.msg().println(
272:                            "Diff result for tables " + tableName1 + " and "
273:                                    + tableName2 + ":");
274:                    ResultTablePrinter.printResult(diffResult);
275:                }
276:            }
277:
278:            /* leave this for testing */
279:            private TableDiffResult getMockResult() {
280:                TableDiffResult result = new TableDiffResult();
281:
282:                Column added = new Column("colname");
283:                added.setDefault("nix");
284:                added.setNullable(true);
285:                added.setPosition(23);
286:                added.setSize(666);
287:                added.setType("myType");
288:                result.addAddedColumn(added);
289:
290:                Column removed = new Column("wech");
291:                removed.setDefault("nix");
292:                removed.setNullable(true);
293:                removed.setPosition(23);
294:                removed.setSize(666);
295:                removed.setType("myType");
296:                result.addRemovedColumn(removed);
297:
298:                Column modOrg = new Column("orischinall");
299:                modOrg.setDefault("orgding");
300:                modOrg.setNullable(true);
301:                modOrg.setPosition(23);
302:                modOrg.setSize(666);
303:                modOrg.setType("myType");
304:
305:                Column modNew = new Column("moddifaied");
306:                modNew.setDefault("modding");
307:                modNew.setNullable(false);
308:                modNew.setPosition(42);
309:                modNew.setSize(999);
310:                modNew.setType("myType");
311:
312:                result.putModifiedColumns(modOrg, modNew);
313:
314:                return result;
315:            }
316:
317:            /* (non-Javadoc)
318:             * @see henplus.Command#complete(henplus.CommandDispatcher, java.lang.String, java.lang.String)
319:             */
320:            public Iterator complete(CommandDispatcher disp,
321:                    String partialCommand, final String lastWord) {
322:
323:                StringTokenizer st = new StringTokenizer(partialCommand);
324:                st.nextToken(); // skip cmd.
325:                int argIndex = st.countTokens();
326:
327:                // System.out.println("[complete] partialCommand: '"+partialCommand+"', lastWord: '" + lastWord+"'");
328:                /*
329:                 * the following input is given:
330:                 * "command token1 [TAB_PRESSED]"
331:                 * in this case the partialCommand is "command token1", the last word has a length 0!
332:                 * 
333:                 * another input:
334:                 * "command toke[TAB_PRESSED]"
335:                 * then the partialCommand is "command toke", the last word is "toke".
336:                 */
337:                if (lastWord.length() > 0) {
338:                    argIndex--;
339:                }
340:
341:                //  =========================  singledb  =======================
342:
343:                // check completion for --singledb
344:                if (argIndex == 0 && lastWord.startsWith("-")) {
345:                    return new Iterator() {
346:                        private boolean _next = true;
347:
348:                        public boolean hasNext() {
349:                            return _next;
350:                        }
351:
352:                        public Object next() {
353:                            _next = false;
354:                            return OPTION_SINGLE_DB;
355:                        }
356:
357:                        public void remove() { /* do nothing */
358:                        }
359:                    };
360:                } else if (partialCommand.indexOf(OPTION_SINGLE_DB) != -1
361:                        && argIndex > 0) {
362:
363:                    SessionManager sessionManager = HenPlus.getInstance()
364:                            .getSessionManager();
365:                    SQLSession session = sessionManager.getCurrentSession();
366:
367:                    final HashSet alreadyGiven = new HashSet();
368:                    while (st.hasMoreElements()) {
369:                        alreadyGiven.add(st.nextToken());
370:                    }
371:                    ListUserObjectsCommand objectList = HenPlus.getInstance()
372:                            .getObjectLister();
373:                    final Iterator iter = objectList.completeTableName(session,
374:                            lastWord);
375:                    return new Iterator() {
376:                        String table = null;
377:
378:                        public boolean hasNext() {
379:                            while (iter.hasNext()) {
380:                                table = (String) iter.next();
381:                                if (alreadyGiven.contains(table)
382:                                        && !lastWord.equals(table)) {
383:                                    continue;
384:                                }
385:                                return true;
386:                            }
387:                            return false;
388:                        }
389:
390:                        public Object next() {
391:                            return table;
392:                        }
393:
394:                        public void remove() {
395:                            throw new UnsupportedOperationException("no!");
396:                        }
397:                    };
398:
399:                }
400:
401:                //  ========================= !singledb  =======================
402:
403:                // !singledb && process the first session
404:                else if (partialCommand.indexOf(OPTION_SINGLE_DB) == -1
405:                        && argIndex == 0) {
406:                    return HenPlus.getInstance().getSessionManager()
407:                            .completeSessionName(lastWord);
408:                }
409:                // !singledb && process the second session
410:                else if (partialCommand.indexOf(OPTION_SINGLE_DB) == -1
411:                        && argIndex == 1) {
412:                    final String firstSession = st.nextToken();
413:                    return getSecondSessionCompleter(lastWord, firstSession);
414:                }
415:                // process tables
416:                else if (argIndex > 1) {
417:                    SessionManager sessionManager = HenPlus.getInstance()
418:                            .getSessionManager();
419:                    SQLSession first = sessionManager.getSessionByName(st
420:                            .nextToken());
421:                    SQLSession second = sessionManager.getSessionByName(st
422:                            .nextToken());
423:
424:                    final HashSet alreadyGiven = new HashSet();
425:                    while (st.hasMoreElements()) {
426:                        alreadyGiven.add(st.nextToken());
427:                    }
428:                    ListUserObjectsCommand objectList = HenPlus.getInstance()
429:                            .getObjectLister();
430:                    final Iterator firstIter = objectList.completeTableName(
431:                            first, lastWord);
432:                    final Iterator secondIter = objectList.completeTableName(
433:                            second, lastWord);
434:                    final Iterator iter = getIntersection(firstIter, secondIter);
435:                    return new Iterator() {
436:                        String table = null;
437:
438:                        public boolean hasNext() {
439:                            while (iter.hasNext()) {
440:                                table = (String) iter.next();
441:                                if (alreadyGiven.contains(table)
442:                                        && !lastWord.equals(table)) {
443:                                    continue;
444:                                }
445:                                return true;
446:                            }
447:                            return false;
448:                        }
449:
450:                        public Object next() {
451:                            return table;
452:                        }
453:
454:                        public void remove() {
455:                            throw new UnsupportedOperationException("no!");
456:                        }
457:                    };
458:                }
459:                return null;
460:            }
461:
462:            private Iterator getIntersection(Iterator first, Iterator second) {
463:                // first copy the first iterator into a list
464:                List contentFirst = new ArrayList();
465:                while (first.hasNext()) {
466:                    contentFirst.add(first.next());
467:                }
468:                // now copy all items of the second iterator into a second list
469:                // which are contained in the first list
470:                List inter = new ArrayList();
471:                while (second.hasNext()) {
472:                    Object next = second.next();
473:                    if (contentFirst.contains(next)) {
474:                        inter.add(next);
475:                    }
476:                }
477:                return inter.iterator();
478:            }
479:
480:            private Iterator getSecondSessionCompleter(String lastWord,
481:                    final String firstSession) {
482:                final Iterator it = HenPlus.getInstance().getSessionManager()
483:                        .completeSessionName(lastWord);
484:                return new Iterator() {
485:                    String session = null;
486:
487:                    public boolean hasNext() {
488:                        while (it.hasNext()) {
489:                            session = (String) it.next();
490:                            if (session.equals(firstSession)) {
491:                                continue;
492:                            }
493:                            return true;
494:                        }
495:                        return false;
496:                    }
497:
498:                    public Object next() {
499:                        return session;
500:                    }
501:
502:                    public void remove() {
503:                        throw new UnsupportedOperationException("no!");
504:                    }
505:                };
506:            }
507:
508:            /* (non-Javadoc)
509:             * @see henplus.Command#isComplete(java.lang.String)
510:             */
511:            public boolean isComplete(String command) {
512:                // HenPlus.msg().println( "[isComplete] command: " + command );
513:                if (command.trim().endsWith(COMMAND_DELIMITER)) {
514:                    return true;
515:                    /*
516:                    StringTokenizer st = new StringTokenizer(command);
517:                    // we need at least four tokens.
518:                    final int minTokens = 4;
519:                    int count = 0;
520:                    while (st.hasMoreTokens() && count < minTokens) {
521:                        count++;
522:                    }
523:                     */
524:                }
525:                return false;
526:            }
527:
528:            /* (non-Javadoc)
529:             * @see henplus.Command#requiresValidSession(java.lang.String)
530:             */
531:            public boolean requiresValidSession(String cmd) {
532:                return false;
533:            }
534:
535:            /* (non-Javadoc)
536:             * @see henplus.Command#shutdown()
537:             */
538:            public void shutdown() {
539:            }
540:
541:            /* (non-Javadoc)
542:             * @see henplus.Command#getShortDescription()
543:             */
544:            public String getShortDescription() {
545:                return "perform a diff on different tables";
546:            }
547:
548:            /* (non-Javadoc)
549:             * @see henplus.Command#getSynopsis(java.lang.String)
550:             */
551:            public String getSynopsis(String cmd) {
552:                return "\n"
553:                        + _command
554:                        + " <sessionname-1> <sessionname-2> (<tablename> | <prefix>* | *)+;\n"
555:                        + "or\n" + _command + " " + OPTION_SINGLE_DB
556:                        + " <table1> <table2>;\n";
557:            }
558:
559:            /* (non-Javadoc)
560:             * @see henplus.Command#getLongDescription(java.lang.String)
561:             */
562:            public String getLongDescription(String cmd) {
563:                return "\tCompare one or more tables by their meta data.\n"
564:                        + "\n"
565:                        + "\tThere are basically two use cases for comparing tables:\n"
566:                        + "\t1. Compare tables with equal names from different databases and\n"
567:                        + "\t2. Compare two tables with different names in the same database.\n"
568:                        + "\n"
569:                        + "\tFor the first use case you must specify two session names and one\n"
570:                        + "\tor more tables that exist in both sessions.\n"
571:                        + "\tYou are able to use wildcards (*) to match all tables or\n"
572:                        + "\ta specific set of tables.\n"
573:                        + "\tE.g. you might specify \"*\" to match all tables which are contained\n"
574:                        + "\tin both sessions, or\"tb_*\" to match all tables from your sessions\n"
575:                        + "\tstarting with \"tb_\".\n"
576:                        + "\n"
577:                        + "\tFor the second use case you must specifiy the option "
578:                        + OPTION_SINGLE_DB
579:                        + "\n"
580:                        + "\tand two tables.\n"
581:                        + "\n"
582:                        + "\tThe following is a list of compared column related\n"
583:                        + "\tproperties, with a \"c\" for a case sensitive and an \"i\" for\n"
584:                        + "\ta case insensitive comparision by default. If you\n"
585:                        + "\twonder what this is for, because you know that sql\n"
586:                        + "\tshould behave case insensitive, then ask your\n"
587:                        + "\tdatabase provider or the developer of the driver you use.\n"
588:                        + "\n"
589:                        + "\t - column name (i)\n"
590:                        + "\t - type (c)\n"
591:                        + "\t - nullable (-)\n"
592:                        + "\t - default value (c)\n"
593:                        + "\t - primary key definition (c)\n"
594:                        + "\t - foreign key definition (c).\n"
595:                        + "\n"
596:                        + "\tIn the future indices migth be added to the comparison,\n"
597:                        + "\tmoreover, an option \"o\" would be nice to get automatically\n"
598:                        + "\t\"ALTER TABLE ...\" scripts generated to a given output file.";
599:            }
600:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.