Source Code Cross Referenced for WbConnection.java in  » Database-Client » SQL-Workbench » workbench » db » 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 » SQL Workbench » workbench.db 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * WbConnection.java
003:         *
004:         * This file is part of SQL Workbench/J, http://www.sql-workbench.net
005:         *
006:         * Copyright 2002-2008, Thomas Kellerer
007:         * No part of this code maybe reused without the permission of the author
008:         *
009:         * To contact the author please send an email to: support@sql-workbench.net
010:         *
011:         */
012:        package workbench.db;
013:
014:        import java.beans.PropertyChangeEvent;
015:        import java.beans.PropertyChangeListener;
016:        import java.io.PrintWriter;
017:        import java.lang.reflect.Field;
018:        import java.lang.reflect.Method;
019:        import java.sql.Connection;
020:        import java.sql.DatabaseMetaData;
021:        import java.sql.DriverManager;
022:        import java.sql.ResultSet;
023:        import java.sql.SQLException;
024:        import java.sql.SQLWarning;
025:        import java.sql.Savepoint;
026:        import java.sql.Statement;
027:        import java.util.ArrayList;
028:        import java.util.Iterator;
029:        import java.util.List;
030:
031:        import workbench.db.report.TagWriter;
032:        import workbench.interfaces.DbExecutionListener;
033:        import workbench.interfaces.StatementRunner;
034:        import workbench.resource.ResourceMgr;
035:        import workbench.util.ExceptionUtil;
036:        import workbench.log.LogMgr;
037:        import workbench.resource.Settings;
038:        import workbench.sql.ScriptParser;
039:        import workbench.sql.preparedstatement.PreparedStatementPool;
040:        import workbench.util.FileUtil;
041:        import workbench.util.StrBuffer;
042:        import workbench.util.StringUtil;
043:
044:        /**
045:         *
046:         * @author  support@sql-workbench.net
047:         */
048:        public class WbConnection implements  DbExecutionListener {
049:            public static final String PROP_CATALOG = "catalog";
050:            public static final String PROP_SCHEMA = "schema";
051:            public static final String PROP_AUTOCOMMIT = "autocommit";
052:            public static final String PROP_CONNECTION_STATE = "state";
053:            public static final String CONNECTION_CLOSED = "closed";
054:            public static final String CONNECTION_OPEN = "open";
055:
056:            private String id;
057:            private StringBuilder scriptError = null;
058:            private Connection sqlConnection;
059:            private DbMetadata metaData;
060:            private ConnectionProfile profile;
061:            private PreparedStatementPool preparedStatementPool;
062:            private List<PropertyChangeListener> listeners;
063:            private DbObjectCache objectCache;
064:
065:            private Method clearSettings = null;
066:            private Object dbAccess = null;
067:            private boolean doOracleClear = true;
068:
069:            private boolean busy;
070:            private KeepAliveDaemon keepAlive = null;
071:
072:            /**
073:             * Create a new wrapper connection around the original SQL connection.
074:             * This will also initialize a {@link #DbMetadata} instance.
075:             */
076:            public WbConnection(String anId, Connection aConn,
077:                    ConnectionProfile aProfile) throws SQLException {
078:                this .id = anId;
079:                setSqlConnection(aConn);
080:                setProfile(aProfile);
081:            }
082:
083:            /**
084:             * Returns the internal ID of this connection.
085:             * 
086:             * @return the internal id of this connection.
087:             */
088:            public String getId() {
089:                return this .id;
090:            }
091:
092:            private void setProfile(ConnectionProfile aProfile) {
093:                this .profile = aProfile;
094:                initKeepAlive();
095:            }
096:
097:            public PreparedStatementPool getPreparedStatementPool() {
098:                if (this .preparedStatementPool == null) {
099:                    this .preparedStatementPool = new PreparedStatementPool(this );
100:                }
101:                return this .preparedStatementPool;
102:            }
103:
104:            public DbObjectCache getObjectCache() {
105:                if (this .objectCache == null) {
106:                    this .objectCache = new DbObjectCache(this );
107:                }
108:                return this .objectCache;
109:            }
110:
111:            public String getCurrentSchema() {
112:                return this .metaData.getCurrentSchema();
113:            }
114:
115:            /**
116:             * Return the name of the current user.
117:             * Wrapper for DatabaseMetaData.getUserName() that throws no Exception
118:             */
119:            public String getCurrentUser() {
120:                try {
121:                    return this .sqlConnection.getMetaData().getUserName();
122:                } catch (Throwable e) {
123:                    return StringUtil.EMPTY_STRING;
124:                }
125:            }
126:
127:            public boolean supportsQueryTimeout() {
128:                if (this .metaData == null)
129:                    return true;
130:                return this .metaData.getDbSettings().supportsQueryTimeout();
131:            }
132:
133:            /**
134:             * @return The profile associated with this connection
135:             */
136:            public ConnectionProfile getProfile() {
137:                return this .profile;
138:            }
139:
140:            void runPreDisconnectScript() {
141:                if (this .profile == null)
142:                    return;
143:                if (this .sqlConnection == null)
144:                    return;
145:                if (this .keepAlive != null) {
146:                    this .keepAlive.shutdown();
147:                }
148:                String sql = profile.getPreDisconnectScript();
149:                runConnectScript(sql, "disconnect");
150:            }
151:
152:            void runPostConnectScript() {
153:                if (this .profile == null)
154:                    return;
155:                if (this .sqlConnection == null)
156:                    return;
157:                String sql = profile.getPostConnectScript();
158:                runConnectScript(sql, "connect");
159:            }
160:
161:            private void runConnectScript(String sql, String type) {
162:                if (StringUtil.isWhitespaceOrEmpty(sql))
163:                    return;
164:                LogMgr.logInfo("WbConnection.runConnectScript()", "Executing "
165:                        + type + " script...");
166:
167:                StatementRunner runner = StatementRunner.Factory.createRunner();
168:                runner.setConnection(this );
169:
170:                ScriptParser p = new ScriptParser(sql);
171:                p
172:                        .setAlternateLineComment(this .getDbSettings()
173:                                .getLineComment());
174:                Iterator itr = p.getIterator();
175:                String command = null;
176:
177:                // The statemenRunner will call clearMessages() when statementDone() 
178:                // is called which in turn will call clearWarnings() on this instances.
179:                // This will also clear the scriptError and thus all messages
180:                // that are collected here. So I have to store the messages locally 
181:                // and cannot use the scriptError variable directly
182:                StringBuilder messages = new StringBuilder(150);
183:
184:                try {
185:                    while (itr.hasNext()) {
186:                        command = p.getNextCommand();
187:                        if (p == null)
188:                            continue;
189:
190:                        try {
191:                            runner.runStatement(command, -1, 0);
192:                        } finally {
193:                            runner.statementDone();
194:                        }
195:                        messages.append(ResourceMgr
196:                                .getString("MsgBatchExecutingStatement"));
197:                        messages.append(": ");
198:                        messages.append(StringUtil
199:                                .getMaxSubstring(command, 250));
200:                        messages.append("\n\n");
201:                    }
202:                } catch (Throwable e) {
203:                    LogMgr.logError("WbConnection.runConnectScript()",
204:                            "Error executing " + type + " script", e);
205:                    messages = new StringBuilder();
206:                    messages.append(ResourceMgr
207:                            .getString("MsgBatchStatementError"));
208:                    messages.append(": ");
209:                    messages.append(command + "\n");
210:                    messages.append(e.getMessage());
211:                } finally {
212:                    if (runner != null)
213:                        runner.done();
214:                }
215:                this .scriptError = messages;
216:            }
217:
218:            void setSqlConnection(Connection aConn) throws SQLException {
219:                this .sqlConnection = aConn;
220:                this .metaData = new DbMetadata(this );
221:                this .doOracleClear = this .metaData.isOracle();
222:            }
223:
224:            /**
225:             * Return any warnings that are stored in the underlying SQL Connection.
226:             * The warnings are then cleared from the connection object.
227:             * 
228:             * @see #clearWarnings()
229:             * @return any warnings reported from the server, null if no warnings are available.
230:             */
231:            public String getWarnings() {
232:                try {
233:
234:                    SQLWarning warn = this .getSqlConnection().getWarnings();
235:                    if (warn == null) {
236:                        if (this .scriptError != null) {
237:                            String error = this .scriptError.toString();
238:                            this .scriptError = null;
239:                            return error;
240:                        }
241:                        return null;
242:                    }
243:
244:                    StringBuilder msg = new StringBuilder(200);
245:                    if (!StringUtil.isEmptyString(this .scriptError))
246:                        msg.append(this .scriptError);
247:
248:                    String s = null;
249:                    while (warn != null) {
250:                        s = warn.getMessage();
251:                        msg.append('\n');
252:                        msg.append(s);
253:                        warn = warn.getNextWarning();
254:                    }
255:                    this .clearWarnings();
256:                    return msg.toString();
257:                } catch (SQLException e) {
258:                    LogMgr.logError("WbConnection.getWarnings()",
259:                            "Error when retrieving SQL Warnings", e);
260:                    return null;
261:                }
262:            }
263:
264:            /**
265:             *	This will clear the warnings from the connection object.
266:             *	Some drivers will not replace existing warnings until clearWarnings()
267:             *	is called, thus SQL Workbench would show the same error message over and
268:             *  over again.
269:             *  This method also works around a bug in the Oracle JDBC driver, because
270:             *	that does not properly clear the warnings list.
271:             */
272:            public void clearWarnings() {
273:                this .scriptError = null;
274:                if (this .sqlConnection == null)
275:                    return;
276:                try {
277:                    this .sqlConnection.clearWarnings();
278:
279:                    if (doOracleClear) {
280:                        // obviously the Oracle driver does NOT clear the warnings
281:                        // (as discovered when looking at the source code)
282:                        // luckily the instance variable on the driver which holds the
283:                        // warnings is defined as public and thus we can
284:                        // reset the warnings "manually"
285:                        // This is done via reflection so that the Oracle driver
286:                        // does not need to be present when compiling
287:                        // this is not true for newer drivers (10.x) 
288:
289:                        if (this .clearSettings == null || dbAccess == null) {
290:                            Class ora = this .sqlConnection.getClass();
291:
292:                            if (ora.getName().equals(
293:                                    "oracle.jdbc.driver.OracleConnection")) {
294:                                Field dbAccessField = ora.getField("db_access");
295:                                Class dbAccessClass = dbAccessField.getType();
296:                                dbAccess = dbAccessField
297:                                        .get(this .sqlConnection);
298:                                try {
299:                                    clearSettings = dbAccessClass.getMethod(
300:                                            "setWarnings",
301:                                            new Class[] { SQLWarning.class });
302:                                } catch (Throwable e) {
303:                                    // newer drivers do not seem to support this any more,
304:                                    // so after the first error, we'll skip this for the rest of the session
305:                                    doOracleClear = false;
306:                                    clearSettings = null;
307:                                }
308:                            }
309:                        }
310:                        // the following line is equivalent to:
311:                        // OracleConnection con = (OracleConnection)this.sqlConnection;
312:                        // con.db_access.setWarnings(null);
313:                        if (clearSettings != null)
314:                            clearSettings.invoke(dbAccess,
315:                                    new Object[] { null });
316:                    }
317:                } catch (Throwable th) {
318:                    LogMgr.logWarning("WbConnection.clearWarnings()",
319:                            "Error resetting warnings!", th);
320:                }
321:            }
322:
323:            public Connection getSqlConnection() {
324:                return this .sqlConnection;
325:            }
326:
327:            public void commit() throws SQLException {
328:                this .sqlConnection.commit();
329:            }
330:
331:            public Savepoint setSavepoint() throws SQLException {
332:                if (this .getAutoCommit())
333:                    return null;
334:                return this .sqlConnection.setSavepoint();
335:            }
336:
337:            /**
338:             * A non-exception throwing wrapper around Connection.rollback(Savepoint)
339:             */
340:            public void rollback(Savepoint sp) {
341:                if (sp == null)
342:                    return;
343:                try {
344:                    this .sqlConnection.rollback(sp);
345:                } catch (Throwable e) {
346:                    LogMgr.logError("WbConnection.rollback(Savepoint)",
347:                            "Error releasing savepoint", e);
348:                }
349:            }
350:
351:            /**
352:             * A non-exception throwing wrapper around Connection.releaseSavepoint(Savepoint)
353:             */
354:            public void releaseSavepoint(Savepoint sp) {
355:                if (sp == null)
356:                    return;
357:                try {
358:                    if (!this .getAutoCommit()) {
359:                        this .sqlConnection.releaseSavepoint(sp);
360:                    }
361:                } catch (Throwable e) {
362:                    LogMgr.logError("WbConnection.releaseSavepoint",
363:                            "Error releasing savepoint", e);
364:                }
365:            }
366:
367:            /**
368:             * Execute a rollback on the connection.
369:             */
370:            public void rollback() throws SQLException {
371:                this .sqlConnection.rollback();
372:            }
373:
374:            public boolean getIgnoreDropErrors() {
375:                if (this .profile != null) {
376:                    return this .profile.getIgnoreDropErrors();
377:                } else {
378:                    return false;
379:                }
380:            }
381:
382:            public void toggleAutoCommit() {
383:                boolean flag = this .getAutoCommit();
384:                try {
385:                    this .setAutoCommit(!flag);
386:                } catch (Exception e) {
387:                    LogMgr.logWarning("WbConnection.toggleAutoCommit()",
388:                            "Error when switching autocommit to " + !flag, e);
389:                }
390:            }
391:
392:            public void setAutoCommit(boolean flag) throws SQLException {
393:                boolean old = this .getAutoCommit();
394:                if (old != flag) {
395:                    this .sqlConnection.setAutoCommit(flag);
396:                    fireConnectionStateChanged(PROP_AUTOCOMMIT, Boolean
397:                            .toString(old), Boolean.toString(flag));
398:                }
399:            }
400:
401:            /**
402:             * Some DBMS (e.g. MySQL) seem to start a new transaction in default 
403:             * isolation mode. Which means that if the SELECT is not committed,
404:             * no changes will be visible until a commit is issued.
405:             * In the DbExplorer this is a problem, as the user has no way
406:             * of sending a commit to end the transation if the DbExplorer
407:             * uses a separate connection.
408:             * The {@link workbench.gui.dbobjects.TableDataPanel} will issue
409:             * a commit after retrieving the data if this method returns true.
410:             * 
411:             * @see workbench.gui.dbobjects.TableDataPanel#doRetrieve(boolean)
412:             * @see workbench.gui.dbobjects.TableDataPanel#showRowCount()
413:             */
414:            public boolean selectStartsTransaction() {
415:                String key = "workbench.db." + this .metaData.getDbId()
416:                        + ".select.startstransaction";
417:                boolean flag = Settings.getInstance().getBoolProperty(key,
418:                        false);
419:                return flag;
420:            }
421:
422:            public boolean getAutoCommit() {
423:                if (this .sqlConnection == null)
424:                    return false;
425:                try {
426:                    return this .sqlConnection.getAutoCommit();
427:                } catch (SQLException e) {
428:                    LogMgr.logWarning("WbConnection.getAutoCommit()",
429:                            "Error when retrieving autoCommit attribute", e);
430:                    return false;
431:                }
432:            }
433:
434:            /**
435:             *	Disconnect this connection. This is delegated to the Connection Manager
436:             *	because for certain DBMS some cleanup works needs to be done.
437:             *  And the ConnectionMgr is the only one who knows if there are more connections
438:             *  around, which might influence what needs to be cleaned up
439:             *  (Currently this is only HSQLDB, but who knows...)
440:             */
441:            public void disconnect() {
442:                ConnectionMgr.getInstance().disconnect(this );
443:                if (this .preparedStatementPool != null) {
444:                    this .preparedStatementPool.done();
445:                }
446:                fireConnectionStateChanged(PROP_CONNECTION_STATE,
447:                        CONNECTION_OPEN, CONNECTION_CLOSED);
448:            }
449:
450:            /**
451:             * This will actually close the connection to the DBMS.
452:             * It will also free an resources from the DbMetadata object and
453:             * shutdown the keep alive thread.
454:             */
455:            public void close() {
456:                if (this .keepAlive != null) {
457:                    this .keepAlive.shutdown();
458:                    this .keepAlive = null;
459:                }
460:
461:                if (this .profile != null
462:                        && this .profile.getRollbackBeforeDisconnect()
463:                        && this .sqlConnection != null) {
464:                    try {
465:                        this .rollback();
466:                    } catch (Exception e) {
467:                        LogMgr
468:                                .logWarning(
469:                                        "WbConnection.close()",
470:                                        "Error when calling rollback before disconnect",
471:                                        e);
472:                    }
473:                }
474:
475:                try {
476:                    if (this .metaData != null)
477:                        this .metaData.close();
478:                    if (this .sqlConnection != null)
479:                        this .sqlConnection.close();
480:                } catch (Throwable th) {
481:                    LogMgr.logWarning("WbConnection.close()",
482:                            "Error when closing connection", th);
483:                } finally {
484:                    this .metaData = null;
485:                    this .sqlConnection = null;
486:                }
487:
488:                LogMgr.logDebug("WbConnection.close()", "Connection "
489:                        + this .getId() + " closed.");
490:
491:                if (Settings.getInstance().getProperty(
492:                        "workbench.db.driver.log", null) != null) {
493:                    PrintWriter pw = DriverManager.getLogWriter();
494:                    FileUtil.closeQuitely(pw);
495:                }
496:
497:            }
498:
499:            public boolean isClosed() {
500:                if (this .sqlConnection == null)
501:                    return true;
502:
503:                try {
504:                    return this .sqlConnection.isClosed();
505:                } catch (Exception e) {
506:                    return true;
507:                }
508:            }
509:
510:            /**
511:             * Create a statement that produces ResultSets that
512:             * are read only and forward only (for performance reasons)
513:             * 
514:             * If the profile defined a default fetch size, this
515:             * will be set as well.
516:             * 
517:             * @throws java.sql.SQLException 
518:             */
519:            public Statement createStatementForQuery() throws SQLException {
520:                Statement stmt = null;
521:                if (getDbSettings().allowsExtendedCreateStatement()) {
522:                    stmt = this .sqlConnection.createStatement(
523:                            ResultSet.TYPE_FORWARD_ONLY,
524:                            ResultSet.CONCUR_READ_ONLY);
525:                } else {
526:                    stmt = this .sqlConnection.createStatement();
527:                }
528:
529:                try {
530:                    if (this .getProfile() != null) {
531:                        int fetchSize = this .getProfile().getFetchSize();
532:                        if (fetchSize > -1)
533:                            stmt.setFetchSize(fetchSize);
534:                    }
535:                } catch (Exception e) {
536:                    LogMgr.logWarning("WbConnection.createStatementForQuery()",
537:                            "Error when setting the fetchSize: "
538:                                    + ExceptionUtil.getDisplay(e));
539:                }
540:                return stmt;
541:            }
542:
543:            public Statement createStatement() throws SQLException {
544:                return this .sqlConnection.createStatement();
545:            }
546:
547:            public boolean supportsSavepoints() {
548:                if (this .sqlConnection == null)
549:                    return false;
550:
551:                try {
552:                    return sqlConnection.getMetaData().supportsSavepoints();
553:                } catch (Throwable e) {
554:                    return false;
555:                }
556:            }
557:
558:            public boolean useJdbcCommit() {
559:                return this .metaData.getDbSettings().useJdbcCommit();
560:            }
561:
562:            public DbSettings getDbSettings() {
563:                return this .metaData.getDbSettings();
564:            }
565:
566:            public DbMetadata getMetadata() {
567:                return this .metaData;
568:            }
569:
570:            public String getUrl() {
571:                try {
572:                    return this .sqlConnection.getMetaData().getURL();
573:                } catch (Throwable e) {
574:                    return null;
575:                }
576:            }
577:
578:            public String toString() {
579:                return getId() + ", " + getCurrentUser() + "@" + getUrl();
580:            }
581:
582:            /**
583:             * Return a readable display of a connection. 
584:             * This might actually send a SELECT to the database to 
585:             * retrieve the current user or schema.
586:             * @see #getCurrentUser()
587:             * @see DbMetadata#getSchemaToUse()
588:             * @see DbMetadata#getCurrentCatalog()
589:             */
590:            public String getDisplayString() {
591:                String displayString = null;
592:                try {
593:                    DbMetadata meta = getMetadata();
594:                    StringBuilder buff = new StringBuilder(100);
595:                    String user = getCurrentUser();
596:                    buff.append(ResourceMgr.getString("TxtUser"));
597:                    buff.append('=');
598:                    buff.append(user);
599:
600:                    String catalog = meta.getCurrentCatalog();
601:                    if (catalog != null && catalog.length() > 0) {
602:                        String catName = meta.getCatalogTerm();
603:                        buff.append(", ");
604:                        buff.append(catName == null ? "Catalog" : StringUtil
605:                                .capitalize(catName));
606:                        buff.append('=');
607:                        buff.append(catalog);
608:                    }
609:
610:                    String schema = meta.getSchemaToUse();
611:                    if (schema != null && !schema.equalsIgnoreCase(user)) {
612:                        String schemaName = meta.getSchemaTerm();
613:                        buff.append(", ");
614:                        buff.append(schemaName == null ? "Schema" : StringUtil
615:                                .capitalize(schemaName));
616:                        buff.append('=');
617:                        buff.append(schema);
618:                    }
619:
620:                    buff.append(", URL=");
621:                    if (getProfile() != null) {
622:                        buff.append(getProfile().getUrl());
623:                    } else {
624:                        buff.append(getSqlConnection().getMetaData().getURL());
625:                    }
626:                    displayString = buff.toString();
627:                } catch (Exception e) {
628:                    LogMgr.logError("ConnectionMgr.getDisplayString()",
629:                            "Could not retrieve connection information", e);
630:                    displayString = getCurrentUser() + "@" + getUrl();
631:                }
632:                return displayString;
633:            }
634:
635:            public String getDatabaseVersion() {
636:                try {
637:                    DatabaseMetaData jdbcmeta = metaData.getJdbcMetadata();
638:                    int major = jdbcmeta.getDatabaseMajorVersion();
639:                    int minor = jdbcmeta.getDatabaseMinorVersion();
640:                    return major + "." + minor;
641:                } catch (Throwable e) {
642:                    LogMgr.logError("WbConnection.getDatabaseVersion()",
643:                            "Error retrieving DB version", e);
644:                    return "n/a";
645:                }
646:            }
647:
648:            public String getDatabaseProductName() {
649:                return this .metaData.getProductName();
650:            }
651:
652:            public String getOutputMessages() {
653:                return this .metaData.getOutputMessages();
654:            }
655:
656:            public int hashCode() {
657:                return this .id.hashCode();
658:            }
659:
660:            public boolean equals(Object o) {
661:                if (o instanceof  WbConnection) {
662:                    return (this .id.equals(((WbConnection) o).id));
663:                }
664:                return false;
665:            }
666:
667:            public StrBuffer getDatabaseInfoAsXml(StrBuffer indent) {
668:                return this .getDatabaseInfoAsXml(indent, null);
669:            }
670:
671:            public String getDriverVersion() {
672:                DatabaseMetaData db = null;
673:                try {
674:                    db = this .sqlConnection.getMetaData();
675:                    return db.getDriverVersion();
676:                } catch (Throwable e) {
677:                    LogMgr.logError("WbConnection.getDriverVersion()",
678:                            "Error retrieving driver version", e);
679:                    return "n/a";
680:                }
681:            }
682:
683:            /**
684:             *	Returns information about the DBMS and the JDBC driver
685:             *	in the XML format used for the XML export
686:             */
687:            public StrBuffer getDatabaseInfoAsXml(StrBuffer indent,
688:                    String namespace) {
689:                StrBuffer dbInfo = new StrBuffer(200);
690:                DatabaseMetaData db = null;
691:                try {
692:                    db = this .sqlConnection.getMetaData();
693:                } catch (Exception e) {
694:                    return new StrBuffer("");
695:                }
696:
697:                TagWriter tagWriter = new TagWriter(namespace);
698:                String value = null;
699:
700:                tagWriter.appendTag(dbInfo, indent, "created", StringUtil
701:                        .getCurrentTimestampWithTZString());
702:
703:                try {
704:                    value = db.getDriverName();
705:                } catch (Throwable th) {
706:                    value = "n/a";
707:                }
708:                tagWriter.appendTag(dbInfo, indent, "jdbc-driver",
709:                        cleanValue(value));
710:
711:                try {
712:                    value = db.getDriverVersion();
713:                } catch (Throwable th) {
714:                    value = "n/a";
715:                }
716:                tagWriter.appendTag(dbInfo, indent, "jdbc-driver-version",
717:                        cleanValue(value));
718:
719:                tagWriter.appendTag(dbInfo, indent, "connection", this 
720:                        .getDisplayString());
721:
722:                try {
723:                    value = db.getDatabaseProductName();
724:                } catch (Throwable th) {
725:                    value = "n/a";
726:                }
727:                tagWriter.appendTag(dbInfo, indent, "database-product-name",
728:                        cleanValue(value));
729:
730:                try {
731:                    value = db.getDatabaseProductVersion();
732:                } catch (Throwable th) {
733:                    value = "n/a";
734:                }
735:                tagWriter.appendTag(dbInfo, indent, "database-product-version",
736:                        cleanValue(value));
737:
738:                return dbInfo;
739:            }
740:
741:            /**
742:             *	Some DBMS have strange characters when reporting their name
743:             *  This method ensures that an XML "compatible" value is returned in
744:             *  getDatabaseInfoAsXml
745:             */
746:            private String cleanValue(String value) {
747:                if (value == null)
748:                    return null;
749:                int len = value.length();
750:                StringBuilder result = new StringBuilder(len);
751:                for (int i = 0; i < len; i++) {
752:                    char c = value.charAt(i);
753:                    if ((c > 32 && c != 127) || c == 9 || c == 10 || c == 13) {
754:                        result.append(c);
755:                    } else {
756:                        result.append(' ');
757:                    }
758:                }
759:                return result.toString();
760:            }
761:
762:            /**
763:             *	Some DBMS need to commit DDL (CREATE, DROP, ...) statements.
764:             *	If the current connection needs a commit for a DDL, this will return true.
765:             *	The metadata class reads the names of those DBMS from the Settings object!
766:             */
767:            protected boolean getDDLNeedsCommit() {
768:                return this .metaData.getDbSettings().ddlNeedsCommit();
769:            }
770:
771:            /**
772:             * Checks if DDL statement need a commit for this connection. 
773:             * 
774:             * @return false if autocommit is on or the DBMS does not support DDL transactions
775:             * @see #getDdlNeedsCommit()
776:             */
777:            public boolean shouldCommitDDL() {
778:                if (this .getAutoCommit())
779:                    return false;
780:                return this .getDDLNeedsCommit();
781:            }
782:
783:            public synchronized void addChangeListener(PropertyChangeListener l) {
784:                if (this .listeners == null)
785:                    this .listeners = new ArrayList<PropertyChangeListener>();
786:                this .listeners.add(l);
787:            }
788:
789:            public synchronized void removeChangeListener(
790:                    PropertyChangeListener l) {
791:                if (this .listeners == null)
792:                    return;
793:                this .listeners.remove(l);
794:            }
795:
796:            private void fireConnectionStateChanged(String property,
797:                    String oldValue, String newValue) {
798:                if (this .listeners != null) {
799:                    int count = this .listeners.size();
800:                    PropertyChangeEvent evt = new PropertyChangeEvent(this ,
801:                            property, oldValue, newValue);
802:                    for (int i = 0; i < count; i++) {
803:                        PropertyChangeListener l = this .listeners.get(i);
804:                        l.propertyChange(evt);
805:                    }
806:                }
807:            }
808:
809:            public void catalogChanged(String oldCatalog, String newCatalog) {
810:                this .fireConnectionStateChanged(PROP_CATALOG, oldCatalog,
811:                        newCatalog);
812:            }
813:
814:            public void schemaChanged(String oldSchema, String newSchema) {
815:                this .fireConnectionStateChanged(PROP_SCHEMA, oldSchema,
816:                        newSchema);
817:            }
818:
819:            private void initKeepAlive() {
820:                if (this .keepAlive != null) {
821:                    this .keepAlive.shutdown();
822:                    this .keepAlive = null;
823:                }
824:
825:                if (this .profile == null)
826:                    return;
827:                String sql = this .profile.getIdleScript();
828:                if (sql == null || sql.trim().length() == 0)
829:                    return;
830:                long idleTime = this .profile.getIdleTime();
831:                if (idleTime <= 0)
832:                    return;
833:                this .keepAlive = new KeepAliveDaemon(idleTime, this , sql);
834:                this .keepAlive.startThread();
835:            }
836:
837:            public boolean isBusy() {
838:                return this .busy;
839:            }
840:
841:            public void setBusy(boolean flag) {
842:                this .busy = flag;
843:                if (flag && this .keepAlive != null) {
844:                    this .keepAlive.setLastDbAction(System.currentTimeMillis());
845:                }
846:            }
847:
848:            public void executionStart(WbConnection conn, Object source) {
849:                if (conn == this ) {
850:                    setBusy(true);
851:                }
852:            }
853:
854:            /*
855:             *	Fired by the SqlPanel if DB access finished
856:             */
857:            public void executionEnd(WbConnection conn, Object source) {
858:                if (conn == this ) {
859:                    setBusy(false);
860:                }
861:            }
862:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.