Source Code Cross Referenced for CopyExecutor.java in  » Database-Client » squirrel-sql-2.6.5a » net » sourceforge » squirrel_sql » plugins » dbcopy » 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 » squirrel sql 2.6.5a » net.sourceforge.squirrel_sql.plugins.dbcopy 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright (C) 2005 Rob Manning
003:         * manningr@users.sourceforge.net
004:         *
005:         * This library is free software; you can redistribute it and/or
006:         * modify it under the terms of the GNU Lesser General Public
007:         * License as published by the Free Software Foundation; either
008:         * version 2.1 of the License, or (at your option) any later version.
009:         *
010:         * This library is distributed in the hope that it will be useful,
011:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
012:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
013:         * Lesser General Public License for more details.
014:         *
015:         * You should have received a copy of the GNU Lesser General Public
016:         * License along with this library; if not, write to the Free Software
017:         * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
018:         */
019:        package net.sourceforge.squirrel_sql.plugins.dbcopy;
020:
021:        import java.sql.PreparedStatement;
022:        import java.sql.ResultSet;
023:        import java.sql.SQLException;
024:        import java.sql.Types;
025:        import java.util.ArrayList;
026:        import java.util.Arrays;
027:        import java.util.Collection;
028:        import java.util.Iterator;
029:        import java.util.List;
030:        import java.util.Set;
031:
032:        import net.sourceforge.squirrel_sql.client.session.ISession;
033:        import net.sourceforge.squirrel_sql.fw.dialects.DialectFactory;
034:        import net.sourceforge.squirrel_sql.fw.dialects.DialectUtils;
035:        import net.sourceforge.squirrel_sql.fw.dialects.UserCancelledOperationException;
036:        import net.sourceforge.squirrel_sql.fw.sql.IDatabaseObjectInfo;
037:        import net.sourceforge.squirrel_sql.fw.sql.ISQLConnection;
038:        import net.sourceforge.squirrel_sql.fw.sql.ISQLDatabaseMetaData;
039:        import net.sourceforge.squirrel_sql.fw.sql.ITableInfo;
040:        import net.sourceforge.squirrel_sql.fw.sql.PrimaryKeyInfo;
041:        import net.sourceforge.squirrel_sql.fw.sql.SQLDatabaseMetaData;
042:        import net.sourceforge.squirrel_sql.fw.sql.SQLUtilities;
043:        import net.sourceforge.squirrel_sql.fw.sql.TableColumnInfo;
044:        import net.sourceforge.squirrel_sql.fw.util.StringManager;
045:        import net.sourceforge.squirrel_sql.fw.util.StringManagerFactory;
046:        import net.sourceforge.squirrel_sql.fw.util.log.ILogger;
047:        import net.sourceforge.squirrel_sql.fw.util.log.LoggerController;
048:        import net.sourceforge.squirrel_sql.plugins.dbcopy.event.AnalysisEvent;
049:        import net.sourceforge.squirrel_sql.plugins.dbcopy.event.CopyEvent;
050:        import net.sourceforge.squirrel_sql.plugins.dbcopy.event.CopyTableListener;
051:        import net.sourceforge.squirrel_sql.plugins.dbcopy.event.ErrorEvent;
052:        import net.sourceforge.squirrel_sql.plugins.dbcopy.event.RecordEvent;
053:        import net.sourceforge.squirrel_sql.plugins.dbcopy.event.StatementEvent;
054:        import net.sourceforge.squirrel_sql.plugins.dbcopy.event.TableEvent;
055:        import net.sourceforge.squirrel_sql.plugins.dbcopy.prefs.DBCopyPreferenceBean;
056:        import net.sourceforge.squirrel_sql.plugins.dbcopy.prefs.PreferencesManager;
057:        import net.sourceforge.squirrel_sql.plugins.dbcopy.util.DBUtil;
058:
059:        import org.hibernate.MappingException;
060:
061:        /**
062:         * This is the class that performs the table copy using database connections 
063:         * to two different database schemas.  
064:         */
065:        public class CopyExecutor extends I18NBaseObject {
066:
067:            /** the class that provides out session information */
068:            SessionInfoProvider prov = null;
069:
070:            /** the source session.  This comes from prov */
071:            ISession sourceSession = null;
072:
073:            /** the destination session.  This comes from prov */
074:            ISession destSession = null;
075:
076:            /** the thread we do the work in */
077:            private Thread execThread = null;
078:
079:            /** what value did autocommit have in dest connection when we received it */
080:            private boolean originalAutoCommitValue = true;
081:
082:            /** what value does autocommit have in dest connection now */
083:            private boolean currentAutoCommitValue = true;
084:
085:            /** the user's preferences */
086:            private static DBCopyPreferenceBean prefs = PreferencesManager
087:                    .getPreferences();
088:
089:            /** Logger for this class. */
090:            private final static ILogger log = LoggerController
091:                    .createLogger(CopyExecutor.class);
092:
093:            /** Internationalized strings for this class. */
094:            private static final StringManager s_stringMgr = StringManagerFactory
095:                    .getStringManager(CopyExecutor.class);
096:
097:            /** the list of ITableInfos that represent the user's last selection. */
098:            private ArrayList<ITableInfo> selectedTableInfos = null;
099:
100:            /** the CopyTableListeners that have registered with this class */
101:            private ArrayList<CopyTableListener> listeners = new ArrayList<CopyTableListener>();
102:
103:            /** whether or not the user cancelled the copy operation */
104:            private volatile boolean cancelled = false;
105:
106:            /** impl that gives us feedback from the user */
107:            private UICallbacks pref = null;
108:
109:            /** the start time in millis that the copy operation began */
110:            private long start = 0;
111:
112:            /** the finish time in millis that the copy operation began */
113:            private long end = 0;
114:
115:            /**
116:             * Constructor.
117:             * 
118:             * @param p the provider of information regarding what to copy where.
119:             */
120:            public CopyExecutor(SessionInfoProvider p) {
121:                prov = p;
122:                sourceSession = prov.getCopySourceSession();
123:                destSession = prov.getCopyDestSession();
124:            }
125:
126:            /**
127:             * Starts the thread that executes the copy operation.
128:             */
129:            public void execute() {
130:                Runnable runnable = new Runnable() {
131:                    public void run() {
132:                        _execute();
133:                    }
134:                };
135:                execThread = new Thread(runnable);
136:                execThread.setName("DBCopy Executor Thread");
137:                execThread.start();
138:            }
139:
140:            /** 
141:             * Cancels the copy operation.
142:             */
143:            public void cancel() {
144:                cancelled = true;
145:                execThread.interrupt();
146:            }
147:
148:            /**
149:             * Performs the table copy operation. 
150:             */
151:            private void _execute() {
152:                start = System.currentTimeMillis();
153:                boolean encounteredException = false;
154:                ISQLConnection destConn = destSession.getSQLConnection();
155:                if (!analyzeTables()) {
156:                    return;
157:                }
158:                setupAutoCommit(destConn);
159:                IDatabaseObjectInfo[] sourceObjs = prov
160:                        .getSourceSelectedDatabaseObjects();
161:                int[] counts = getTableCounts();
162:                sendCopyStarted(counts);
163:                String destSchema = prov.getDestSelectedDatabaseObject()
164:                        .getSimpleName();
165:                String destCatalog = prov.getDestSelectedDatabaseObject()
166:                        .getCatalogName();
167:                for (int i = 0; i < sourceObjs.length; i++) {
168:                    if (false == sourceObjs[i] instanceof  ITableInfo) {
169:                        continue;
170:                    }
171:                    ITableInfo sourceTI = (ITableInfo) sourceObjs[i];
172:                    sendTableCopyStarted(sourceTI, i + 1);
173:                    try {
174:                        int destTableCount = DBUtil.getTableCount(destSession,
175:                                destCatalog, destSchema, sourceTI
176:                                        .getSimpleName(),
177:                                DialectFactory.DEST_TYPE);
178:                        if (destTableCount == -1) {
179:                            createTable(sourceTI);
180:                        }
181:                        if (destTableCount > 0) {
182:                            try {
183:                                String t = sourceTI.getSimpleName();
184:                                if (pref.appendRecordsToExisting(t)) {
185:                                    /* Do nothing */
186:                                } else if (pref.deleteTableData(sourceTI
187:                                        .getSimpleName())) {
188:                                    // Yes || Yes to all
189:                                    DBUtil.deleteDataInExistingTable(
190:                                            destSession, destCatalog,
191:                                            destSchema, sourceTI
192:                                                    .getSimpleName());
193:                                } else {
194:                                    continue; // skip this table, try the next.
195:                                }
196:
197:                            } catch (UserCancelledOperationException e) {
198:                                cancelled = true;
199:                                break;
200:                            }
201:                        }
202:
203:                        copyTable(sourceTI, counts[i]);
204:
205:                        if (i == sourceObjs.length - 1 && !cancelled) {
206:                            // We just copied the last table.  Now it is safe to copy the
207:                            // constraints.(Well, that is, if all FK dependencies are met
208:                            // in the group of tables being copied. 
209:                            // TODO: new feature could be to examine table list for FK's 
210:                            // in tables not in the list then prompt the user to add 
211:                            // those missing tables to the list.
212:                            copyConstraints(sourceObjs);
213:                        }
214:                        if (!cancelled) {
215:                            sendTableCopyFinished(sourceTI, i + 1);
216:                            sleep(prefs.getTableDelayMillis());
217:                        }
218:                    } catch (SQLException e) {
219:                        encounteredException = true;
220:                        sendErrorEvent(ErrorEvent.SQL_EXCEPTION_TYPE, e);
221:                        break;
222:                    } catch (MappingException e) {
223:                        encounteredException = true;
224:                        sendErrorEvent(ErrorEvent.MAPPING_EXCEPTION_TYPE, e);
225:                        break;
226:                    } catch (UserCancelledOperationException e) {
227:                        cancelled = true;
228:                        break;
229:                    } catch (Exception e) {
230:                        encounteredException = true;
231:                        sendErrorEvent(ErrorEvent.GENERIC_EXCEPTION, e);
232:                        break;
233:                    }
234:                }
235:                restoreAutoCommit(destConn);
236:                if (cancelled) {
237:                    sendErrorEvent(ErrorEvent.USER_CANCELLED_EXCEPTION_TYPE);
238:                    return;
239:                }
240:                if (encounteredException) {
241:                    return;
242:                }
243:                end = System.currentTimeMillis();
244:
245:                ISession session = prov.getCopyDestSession();
246:                session.getSchemaInfo().reload(
247:                        prov.getDestSelectedDatabaseObject());
248:                session.getSchemaInfo().fireSchemaInfoUpdate();
249:
250:                notifyCopyFinished();
251:            }
252:
253:            /**
254:             * Registers the specified listener to receive copy events from this class.
255:             * 
256:             * @param listener
257:             */
258:            public void addListener(CopyTableListener listener) {
259:                if (listener == null) {
260:                    throw new IllegalArgumentException(
261:                            "listener cannot be null");
262:                }
263:                listeners.add(listener);
264:            }
265:
266:            /**
267:             * Causes the current thread to sleep for the amount of time specified if 
268:             * sleepTime > 0.  No effect for sleepTime <= 0.
269:             * 
270:             * @param sleepTime time in milliseconds to make the current thread sleep.
271:             */
272:            private void sleep(long sleepTime) {
273:                boolean shouldSleep = prefs.isDelayBetweenObjects();
274:                if (!shouldSleep || sleepTime <= 0) {
275:                    return;
276:                }
277:                try {
278:                    Thread.sleep(sleepTime);
279:                } catch (InterruptedException e) {
280:                    // Do Nothing
281:                }
282:            }
283:
284:            /**
285:             * For all selected tables, loop through their columns and see if the column
286:             * name can be used as a column name in the destination database.  This 
287:             * method will send an error event if a table has any column names that 
288:             * cannot be used in the destination database.  This method just returns
289:             * true if the user preference is not to test column names.  
290:             * 
291:             * @return true if the tables can be created in the destination database; 
292:             *         false is returned otherwise.
293:             */
294:            private boolean analyzeTables() {
295:                boolean result = true;
296:                if (!prefs.isTestColumnNames()) {
297:                    return true;
298:                }
299:                if (DBUtil.sameDatabaseType(prov.getCopySourceSession(), prov
300:                        .getCopyDestSession())) {
301:                    // No need to check column name validity when source and dest are
302:                    // of the same type of database.
303:                    return true;
304:                }
305:                sendAnalysisStarted();
306:                try {
307:                    IDatabaseObjectInfo[] dbObjs = prov
308:                            .getSourceSelectedDatabaseObjects();
309:                    for (int tableIdx = 0; tableIdx < dbObjs.length; tableIdx++) {
310:                        ITableInfo ti = (ITableInfo) dbObjs[tableIdx];
311:                        sendAnalyzingTable(ti, tableIdx);
312:                        DBUtil.validateColumnNames(ti, prov);
313:                    }
314:                } catch (MappingException e) {
315:                    sendErrorEvent(ErrorEvent.MAPPING_EXCEPTION_TYPE, e);
316:                    result = false;
317:                } catch (UserCancelledOperationException e) {
318:                    sendErrorEvent(ErrorEvent.USER_CANCELLED_EXCEPTION_TYPE, e);
319:                    result = false;
320:                }
321:                return result;
322:            }
323:
324:            /**
325:             * Setup the auto-commit setting on the specified connection to 
326:             * the user's preference.
327:             * 
328:             * @param con
329:             */
330:            private void setupAutoCommit(ISQLConnection con) {
331:                boolean autoCommitPref = prefs.isAutoCommitEnabled();
332:                try {
333:                    originalAutoCommitValue = con.getAutoCommit();
334:                    currentAutoCommitValue = originalAutoCommitValue;
335:                    if (autoCommitPref != originalAutoCommitValue) {
336:                        con.setAutoCommit(autoCommitPref);
337:                        currentAutoCommitValue = autoCommitPref;
338:                    }
339:                } catch (SQLException e) {
340:                    // Don't fool around with manual commit later.
341:                    currentAutoCommitValue = true;
342:                    sendErrorEvent(ErrorEvent.SETUP_AUTO_COMMIT_TYPE, e);
343:                }
344:
345:            }
346:
347:            /**
348:             * Restore the auto-commit setting on the specified connection to the 
349:             * whatever it was previous to our manipulation
350:             * 
351:             * @param con
352:             */
353:            private void restoreAutoCommit(ISQLConnection con) {
354:                if (originalAutoCommitValue == currentAutoCommitValue) {
355:                    return;
356:                }
357:                try {
358:                    con.setAutoCommit(originalAutoCommitValue);
359:                } catch (SQLException e) {
360:                    sendErrorEvent(ErrorEvent.RESTORE_AUTO_COMMIT_TYPE, e);
361:                }
362:            }
363:
364:            private int[] getTableCounts() {
365:                int[] result = null;
366:
367:                ISession sourceSession = prov.getCopySourceSession();
368:                IDatabaseObjectInfo[] dbObjs = prov
369:                        .getSourceSelectedDatabaseObjects();
370:                if (dbObjs != null) {
371:                    result = new int[dbObjs.length];
372:                    selectedTableInfos = new ArrayList<ITableInfo>();
373:                    for (int i = 0; i < dbObjs.length; i++) {
374:                        if (false == dbObjs[i] instanceof  ITableInfo) {
375:                            continue;
376:                        }
377:                        try {
378:                            ITableInfo ti = (ITableInfo) dbObjs[i];
379:                            selectedTableInfos.add(ti);
380:                            // This doesn't appear to work for PROGRESS RDBMS
381:                            //result[i] = DBUtil.getTableCount(con, ti.getSimpleName());
382:                            result[i] = DBUtil.getTableCount(sourceSession, ti
383:                                    .getCatalogName(), ti.getSchemaName(), ti
384:                                    .getSimpleName(),
385:                                    DialectFactory.SOURCE_TYPE);
386:                        } catch (Exception e) {
387:                            log.error("", e);
388:                            result[i] = 0;
389:                        }
390:                    }
391:                }
392:                return result;
393:            }
394:
395:            private void sendAnalysisStarted() {
396:                AnalysisEvent event = new AnalysisEvent(prov);
397:                Iterator<CopyTableListener> i = listeners.iterator();
398:                while (i.hasNext()) {
399:                    CopyTableListener listener = i.next();
400:                    listener.tableAnalysisStarted(event);
401:                }
402:            }
403:
404:            private void sendAnalyzingTable(ITableInfo ti, int number) {
405:                TableEvent event = new TableEvent(prov);
406:                event
407:                        .setTableCount(prov.getSourceSelectedDatabaseObjects().length);
408:                event.setTableNumber(number);
409:                Iterator<CopyTableListener> i = listeners.iterator();
410:                event.setTableName(ti.getSimpleName());
411:                while (i.hasNext()) {
412:                    CopyTableListener listener = i.next();
413:                    listener.analyzingTable(event);
414:                }
415:            }
416:
417:            private void sendCopyStarted(int[] tableCounts) {
418:                CopyEvent event = new CopyEvent(prov);
419:                event.setTableCounts(tableCounts);
420:                Iterator<CopyTableListener> i = listeners.iterator();
421:                while (i.hasNext()) {
422:                    CopyTableListener listener = i.next();
423:                    listener.copyStarted(event);
424:                }
425:            }
426:
427:            private void sendTableCopyStarted(ITableInfo ti, int number) {
428:                TableEvent event = new TableEvent(prov);
429:                event.setTableNumber(number);
430:                event
431:                        .setTableCount(prov.getSourceSelectedDatabaseObjects().length);
432:                event.setTableName(ti.getSimpleName());
433:                Iterator<CopyTableListener> i = listeners.iterator();
434:                while (i.hasNext()) {
435:                    CopyTableListener listener = i.next();
436:                    listener.tableCopyStarted(event);
437:                }
438:            }
439:
440:            private void sendTableCopyFinished(ITableInfo ti, int number) {
441:                TableEvent event = new TableEvent(prov);
442:                event.setTableNumber(number);
443:                event
444:                        .setTableCount(prov.getSourceSelectedDatabaseObjects().length);
445:                event.setTableName(ti.getSimpleName());
446:                Iterator<CopyTableListener> i = listeners.iterator();
447:                while (i.hasNext()) {
448:                    CopyTableListener listener = i.next();
449:                    listener.tableCopyFinished(event);
450:                }
451:            }
452:
453:            /**
454:             * Send an error event message to all CopyTableListeners
455:             * @param type the type of the ErrorEvent.
456:             */
457:            private void sendErrorEvent(int type) {
458:                sendErrorEvent(type, null);
459:            }
460:
461:            /**
462:             * Send an error event message to all CopyTableListeners
463:             * @param type the type of the ErrorEvent.
464:             * @param e the exception that was encountered.
465:             */
466:            private void sendErrorEvent(int type, Exception e) {
467:                ErrorEvent event = new ErrorEvent(prov, type);
468:                event.setException(e);
469:                Iterator<CopyTableListener> i = listeners.iterator();
470:                while (i.hasNext()) {
471:                    CopyTableListener listener = i.next();
472:                    listener.handleError(event);
473:                }
474:            }
475:
476:            private void sendRecordEvent(int number, int count) {
477:                RecordEvent event = new RecordEvent(prov, number, count);
478:                Iterator<CopyTableListener> i = listeners.iterator();
479:                while (i.hasNext()) {
480:                    CopyTableListener listener = i.next();
481:                    listener.recordCopied(event);
482:                }
483:            }
484:
485:            private void sendStatementEvent(String sql, String[] vals) {
486:                StatementEvent event = new StatementEvent(sql,
487:                        StatementEvent.INSERT_RECORD_TYPE);
488:                event.setBindValues(vals);
489:                Iterator<CopyTableListener> i = listeners.iterator();
490:                while (i.hasNext()) {
491:                    CopyTableListener listener = i.next();
492:                    listener.statementExecuted(event);
493:                }
494:            }
495:
496:            private void notifyCopyFinished() {
497:                int seconds = (int) getElapsedSeconds();
498:                Iterator<CopyTableListener> i = listeners.iterator();
499:                while (i.hasNext()) {
500:                    CopyTableListener listener = i.next();
501:                    listener.copyFinished(seconds);
502:                }
503:            }
504:
505:            /**
506:             * 
507:             * @return
508:             */
509:            private long getElapsedSeconds() {
510:                long result = 1;
511:                double elapsed = end - start;
512:                if (elapsed > 1000) {
513:                    result = Math.round(elapsed / 1000);
514:                }
515:                return result;
516:            }
517:
518:            /**
519:             * 
520:             * @param sourceTableInfo
521:             * @param sourceTableCount
522:             * @throws MappingException
523:             * @throws SQLException
524:             */
525:            private void copyTable(ITableInfo sourceTableInfo,
526:                    int sourceTableCount) throws MappingException,
527:                    SQLException, UserCancelledOperationException {
528:                PreparedStatement insertStmt = null;
529:                ResultSet rs = null;
530:                if (cancelled) {
531:                    return;
532:                }
533:                if (!PreferencesManager.getPreferences().isCopyData()) {
534:                    return;
535:                }
536:                ISQLConnection sourceConn = prov.getCopySourceSession()
537:                        .getSQLConnection();
538:                ISQLConnection destConn = prov.getCopyDestSession()
539:                        .getSQLConnection();
540:                SQLDatabaseMetaData sourceMetaData = sourceConn
541:                        .getSQLMetaData();
542:                SQLDatabaseMetaData destMetaData = destConn.getSQLMetaData();
543:                try {
544:                    String destSchema = prov.getDestSelectedDatabaseObject()
545:                            .getSimpleName();
546:                    ITableInfo destTableInfo = DBUtil.getTableInfo(prov
547:                            .getCopyDestSession(), destSchema, sourceTableInfo
548:                            .getSimpleName());
549:
550:                    TableColumnInfo[] sourceInfos = sourceMetaData
551:                            .getColumnInfo(sourceTableInfo);
552:                    TableColumnInfo[] destInfos = destMetaData
553:                            .getColumnInfo(destTableInfo);
554:
555:                    destInfos = sort(sourceInfos, destInfos, sourceTableInfo
556:                            .getQualifiedName(), destTableInfo
557:                            .getQualifiedName());
558:
559:                    String sourceColList = DBUtil.getColumnList(sourceInfos);
560:                    String destColList = DBUtil.getColumnList(destInfos);
561:
562:                    String selectSQL = DBUtil.getSelectQuery(prov,
563:                            sourceColList, sourceTableInfo);
564:                    String insertSQL = DBUtil.getInsertSQL(prov, destColList,
565:                            sourceTableInfo, destInfos.length);
566:                    insertStmt = destConn.prepareStatement(insertSQL);
567:
568:                    int count = 1;
569:                    int commitCount = prefs.getCommitCount();
570:                    int columnCount = destInfos.length;
571:                    String[] bindVarVals = new String[columnCount];
572:
573:                    boolean foundLOBType = false;
574:                    // Loop through source records...
575:                    DBUtil.setLastStatement(selectSQL);
576:                    rs = DBUtil.executeQuery(prov.getCopySourceSession(),
577:                            selectSQL);
578:                    DBUtil.setLastStatement(insertSQL);
579:                    boolean isMysql = DialectFactory.isMySQL(destSession
580:                            .getMetaData());
581:                    boolean isSourceOracle = DialectFactory
582:                            .isOracle(sourceSession.getMetaData());
583:                    boolean isDestOracle = DialectFactory.isOracle(destSession
584:                            .getMetaData());
585:                    while (rs.next() && !cancelled) {
586:                        // MySQL driver gets unhappy when we use the same 
587:                        // PreparedStatement to bind null and non-null LOB variables
588:                        // without clearing the parameters first.
589:                        if (isMysql && foundLOBType) {
590:                            insertStmt.clearParameters();
591:                        }
592:                        StringBuilder lastStmtValuesBuffer = new StringBuilder();
593:                        lastStmtValuesBuffer
594:                                .append("\n(Bind variable values: ");
595:                        for (int i = 0; i < columnCount; i++) {
596:
597:                            int sourceColType = sourceInfos[i].getDataType();
598:                            // If source column is type 1111 (OTHER), try to use the 
599:                            // column type name to find a type that isn't 1111.
600:                            sourceColType = DBUtil
601:                                    .replaceOtherDataType(sourceInfos[i]);
602:                            sourceColType = getDateReplacement(sourceColType,
603:                                    isSourceOracle);
604:
605:                            int destColType = destInfos[i].getDataType();
606:                            // If source column is type 1111 (OTHER), try to use the 
607:                            // column type name to find a type that isn't 1111.
608:                            destColType = DBUtil
609:                                    .replaceOtherDataType(destInfos[i]);
610:                            destColType = getDateReplacement(destColType,
611:                                    isDestOracle);
612:
613:                            String bindVal = DBUtil.bindVariable(insertStmt,
614:                                    sourceColType, destColType, i + 1, rs);
615:                            bindVarVals[i] = bindVal;
616:                            lastStmtValuesBuffer.append(bindVal);
617:                            if (i + 1 < columnCount) {
618:                                lastStmtValuesBuffer.append(", ");
619:                            }
620:                            if (isLOBType(destColType)) {
621:                                foundLOBType = true;
622:                            }
623:                        }
624:                        lastStmtValuesBuffer.append(")");
625:                        DBUtil.setLastStatementValues(lastStmtValuesBuffer
626:                                .toString());
627:                        sendStatementEvent(insertSQL, bindVarVals);
628:                        insertStmt.executeUpdate();
629:                        sendRecordEvent(count, sourceTableCount);
630:                        count++;
631:                        if (!currentAutoCommitValue) {
632:                            if ((count % commitCount) == 0) {
633:                                commitConnection(destConn);
634:                            }
635:                        }
636:                        sleep(prefs.getRecordDelayMillis());
637:                    }
638:                } finally {
639:                    SQLUtilities.closeResultSet(rs);
640:                    SQLUtilities.closeStatement(insertStmt);
641:                    if (!currentAutoCommitValue) {
642:                        commitConnection(destConn);
643:                    }
644:                }
645:            }
646:
647:            /**
648:             * This will return a TIMESTAMP type when the specified type is a DATE and 
649:             * isOracle is true.  This is done so that Oracle dates that have a time 
650:             * component, will have the time component copied correctly.
651:             *  
652:             * @param session
653:             * @param type
654:             * @param isOracle
655:             * @return
656:             */
657:            private int getDateReplacement(int type, boolean isOracle) {
658:                int result = type;
659:                if (isOracle && type == java.sql.Types.DATE) {
660:                    result = java.sql.Types.TIMESTAMP;
661:                }
662:                return result;
663:            }
664:
665:            /**
666:             * Returns a boolean value indicating whether or not the specific column
667:             * type is a binary or LOB column.
668:             * @param columnType the JDBC type.
669:             * 
670:             * @return true if the specified type is LOB; false otherwise.
671:             */
672:            private boolean isLOBType(int columnType) {
673:                if (columnType == Types.BLOB || columnType == Types.CLOB
674:                        || columnType == Types.LONGVARBINARY
675:                        || columnType == Types.BINARY) {
676:                    return true;
677:                }
678:                return false;
679:            }
680:
681:            /**
682:             * Sorts the specified destInfos array based on the order of the sourceInfos
683:             * array.  Not a very efficient algorthim, but it gets the job done.
684:             * TODO: rewrite this using Collections sorting capability.
685:             * 
686:             * @param sourceInfos
687:             * @param destInfos
688:             * @param sourceTableName
689:             * @param destTableName
690:             * @return a re-ordered version of the specified destInfos array
691:             * @throws MappingException if the arrays differ in length or column names.
692:             */
693:            private TableColumnInfo[] sort(TableColumnInfo[] sourceInfos,
694:                    TableColumnInfo[] destInfos, String sourceTableName,
695:                    String destTableName) throws MappingException {
696:                if (sourceInfos.length != destInfos.length) {
697:                    //i18n[CopyExecutor.tablecolmismatch=Column count for table {0} in 
698:                    //source database is {1}, but column count for table {2} in 
699:                    //destination database is {3}
700:                    String msg = s_stringMgr.getString(
701:                            "CopyExecutor.tablecolmismatch", new Object[] {
702:                                    sourceTableName,
703:                                    Integer.valueOf(sourceInfos.length),
704:                                    destTableName,
705:                                    Integer.valueOf(destInfos.length) });
706:                    throw new MappingException(msg);
707:                }
708:                ArrayList<TableColumnInfo> result = new ArrayList<TableColumnInfo>();
709:
710:                for (int sourceIdx = 0; sourceIdx < sourceInfos.length; sourceIdx++) {
711:                    TableColumnInfo sourceInfo = sourceInfos[sourceIdx];
712:                    // trim the column name in case of HADB
713:                    String sourceColumnName = sourceInfo.getColumnName().trim();
714:                    boolean found = false;
715:                    int destIdx = 0;
716:                    while (!found && destIdx < destInfos.length) {
717:                        TableColumnInfo destInfo = destInfos[destIdx];
718:                        // trim the column name in case of HADB
719:                        String destColumnName = destInfo.getColumnName().trim();
720:                        if (destColumnName.equalsIgnoreCase(sourceColumnName)) {
721:                            result.add(destInfo);
722:                            found = true;
723:                        }
724:                        destIdx++;
725:                    }
726:                    if (!found) {
727:                        throw new MappingException("Destination table "
728:                                + destTableName
729:                                + " doesn't appear to have a column named "
730:                                + sourceInfo.getColumnName());
731:                    }
732:                }
733:                return result.toArray(new TableColumnInfo[destInfos.length]);
734:            }
735:
736:            /**
737:             * Commit the specified Connection and log any SQLExceptions that might 
738:             * occur.
739:             * 
740:             * @param connection
741:             */
742:            private void commitConnection(ISQLConnection connection) {
743:                try {
744:                    connection.commit();
745:                } catch (SQLException e) {
746:                    log.error("Failed to commit connection - " + connection, e);
747:                }
748:            }
749:
750:            /**
751:             * Copies the foreign key constraints.  Primary keys are created in the table
752:             * create statement, since some databases don't support adding primary keys
753:             * after table creation. This will have no effect when using Axion as the 
754:             * source database.
755:             *  
756:             * @param sourceConn
757:             * @param destConn
758:             * @param ti
759:             * @throws SQLException
760:             */
761:            private void copyConstraints(IDatabaseObjectInfo[] dbObjs)
762:                    throws SQLException, UserCancelledOperationException {
763:                if (!prefs.isCopyForeignKeys()
764:                        || DialectFactory.isAxion(prov.getCopySourceSession()
765:                                .getMetaData())) {
766:                    return;
767:                }
768:                ISQLConnection destConn = prov.getCopyDestSession()
769:                        .getSQLConnection();
770:                for (int i = 0; i < dbObjs.length; i++) {
771:                    ITableInfo ti = (ITableInfo) dbObjs[i];
772:                    Set<String> fkStmts = DBUtil.getForeignKeySQL(prov, ti,
773:                            selectedTableInfos);
774:                    Iterator<String> it = fkStmts.iterator();
775:                    while (it.hasNext()) {
776:                        String fkSQL = it.next();
777:                        DBUtil.setLastStatementValues("");
778:                        try {
779:                            DBUtil.executeUpdate(destConn, fkSQL, true);
780:                        } catch (SQLException e) {
781:                            log
782:                                    .error(
783:                                            "Unexpected exception while attempting to "
784:                                                    + "create FK constraint using sql = "
785:                                                    + fkSQL, e);
786:                        }
787:                    }
788:                }
789:            }
790:
791:            private void createTable(ITableInfo ti) throws SQLException,
792:                    UserCancelledOperationException, MappingException {
793:                if (cancelled) {
794:                    return;
795:                }
796:                ISQLConnection destCon = prov.getCopyDestSession()
797:                        .getSQLConnection();
798:                String createTableSql = DBUtil.getCreateTableSql(prov, ti);
799:                DBUtil.executeUpdate(destCon, createTableSql, true);
800:
801:                if (prefs.isCommitAfterTableDefs() && !currentAutoCommitValue) {
802:                    commitConnection(destCon);
803:                }
804:
805:                if (prefs.isCopyIndexDefs()) {
806:                    Collection<String> indices = null;
807:                    ISQLDatabaseMetaData sqlmd = sourceSession.getMetaData();
808:                    if (prefs.isCopyPrimaryKeys()) {
809:                        PrimaryKeyInfo[] pkList = sqlmd.getPrimaryKey(ti);
810:                        List<PrimaryKeyInfo> pkList2 = Arrays.asList(pkList);
811:                        indices = DialectUtils
812:                                .createIndexes(ti, sqlmd, pkList2);
813:                    } else {
814:                        indices = DialectUtils.createIndexes(ti, sqlmd, null);
815:                    }
816:                    Iterator<String> i = indices.iterator();
817:                    while (i.hasNext()) {
818:                        String createIndicesSql = i.next();
819:                        DBUtil.executeUpdate(destCon, createIndicesSql, true);
820:                    }
821:                }
822:            }
823:
824:            /**
825:             * @param pref The pref to set.
826:             */
827:            public void setPref(UICallbacks pref) {
828:                this .pref = pref;
829:            }
830:
831:            /**
832:             * @return Returns the pref.
833:             */
834:            public UICallbacks getPref() {
835:                return pref;
836:            }
837:
838:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.