2 * Copyright (C) 2007 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
6 * The contents of this file are subject to the Mozilla Public License VeresultSetion 1.1
7 * See LICENSE.TXT at the top of this package for the full license terms.
10 package eu
.etaxonomy
.cdm
.database
;
12 import java
.io
.PrintWriter
;
13 import java
.sql
.Connection
;
14 import java
.sql
.DatabaseMetaData
;
15 import java
.sql
.DriverManager
;
16 import java
.sql
.ResultSet
;
17 import java
.sql
.SQLException
;
18 import java
.sql
.Statement
;
19 import java
.util
.HashMap
;
22 import org
.apache
.log4j
.Logger
;
24 import eu
.etaxonomy
.cdm
.config
.CdmSource
;
25 import eu
.etaxonomy
.cdm
.config
.CdmSourceException
;
26 import eu
.etaxonomy
.cdm
.database
.types
.IDatabaseType
;
27 import eu
.etaxonomy
.cdm
.model
.metadata
.CdmMetaData
.MetaDataPropertyName
;
34 abstract class CdmDataSourceBase
extends CdmSource
implements ICdmDataSource
{
37 private static final Logger logger
= Logger
.getLogger(CdmDataSourceBase
.class);
40 // private static final int TIMEOUT = 10;
41 private Connection connection
;
45 public Connection
getConnection() throws SQLException
{
46 return getConnection(getUsername(), getPassword());
51 public Connection
getConnection(String username
, String password
) throws SQLException
{
53 if(connection
!= null){
54 boolean isValid
= true;
56 // isValid = connection.isValid(TIMEOUT);
57 // } catch (java.lang.AbstractMethodError e){
58 // logger.error("Problems with Connection.isValid method\n" + "Exception: " + e.toString());
64 IDatabaseType dbType
= getDatabaseType().getDatabaseType();
65 String classString
= dbType
.getClassString();
66 Class
.forName(classString
);
67 String mUrl
= dbType
.getConnectionString(this);
68 Connection connection
= DriverManager
.getConnection(mUrl
, username
, password
);
71 } catch (ClassNotFoundException e
) {
72 throw new RuntimeException("Database driver class could not be loaded\n" + "Exception: " + e
.toString(),e
);
73 } catch(SQLException e
) {
74 throw new RuntimeException("Problems with database connection\n" + "Exception: " + e
.toString(), e
);
80 public boolean testConnection() throws ClassNotFoundException
, SQLException
{
82 IDatabaseType dbType
= getDatabaseType().getDatabaseType();
83 String classString
= dbType
.getClassString();
84 Class
.forName(classString
);
85 String mUrl
= dbType
.getConnectionString(this);
86 if(logger
.isDebugEnabled()){
87 logger
.debug("testConnection() : " + mUrl
);
90 if(logger
.isDebugEnabled()){
91 logger
.debug("testConnection() : " + mUrl
+ " : service is available");
93 // try to connect to the database server
94 Connection connection
= DriverManager
.getConnection(mUrl
, getUsername(), getPassword());
95 if (connection
!= null){
96 if(logger
.isDebugEnabled()){
97 logger
.debug("testConnection() : " + mUrl
+ " : jdbc connect successful");
102 if(logger
.isDebugEnabled()){
103 logger
.debug("testConnection() : " + mUrl
+ " : FAIL");
109 public boolean checkConnection() throws CdmSourceException
{
111 return testConnection();
112 } catch (ClassNotFoundException e
) {
113 throw new CdmSourceException(e
.getMessage());
114 } catch (SQLException e
) {
115 throw new CdmSourceException(e
.getMessage());
121 public String
getConnectionMessage() {
123 if (getDatabaseType().equals(DatabaseTypeEnum
.H2
)) {
124 message
= " local CDM Store ";
126 message
= " CDM Community Store ";
128 message
+= "'" + getName() + "'";
130 message
= "Connecting to" + message
+ ".";
136 public Object
getSingleValue(String query
) throws SQLException
{
137 String queryString
= query
== null?
"(null)": query
;
138 ResultSet resultSet
= executeQuery(query
);
139 if (resultSet
== null || resultSet
.next() == false){
140 logger
.info("No record returned for query " + queryString
);
143 if (resultSet
.getMetaData().getColumnCount() != 1){
144 logger
.info("More than one column selected in query" + queryString
);
145 //first value will be taken
147 Object object
= resultSet
.getObject(1);
148 if (resultSet
.next()){
149 logger
.info("Multiple results for query " + queryString
);
150 //first row will be taken
156 public String
getDbSchemaVersion() throws CdmSourceException
{
158 return (String
)getSingleValue(MetaDataPropertyName
.DB_SCHEMA_VERSION
.getSqlQuery());
159 } catch (SQLException e
) {
160 throw new CdmSourceException(e
.getMessage());
165 public boolean isDbEmpty() throws CdmSourceException
{
166 // Any CDM DB should have a schema version
167 String dbSchemaVersion
= (String
) getDbSchemaVersion();
169 return (dbSchemaVersion
== null || dbSchemaVersion
.equals(""));
173 * Executes a query and returns the ResultSet.
174 * @return ResultSet for the query.
175 * @throws SQLException
178 public ResultSet
executeQuery (String query
) throws SQLException
{
185 Connection connection
= getConnection();
186 if (connection
!= null){
187 Statement statement
= connection
.createStatement();
188 resultSet
= statement
.executeQuery(query
);
190 throw new RuntimeException("Could not establish connection to database");
197 public int executeUpdate (String sqlUpdate
) throws SQLException
{
200 Connection connection
= null;
202 if (sqlUpdate
== null){
205 connection
= getConnection();
206 Statement statement
= connection
.createStatement();
207 result
= statement
.executeUpdate(sqlUpdate
);
209 } catch(SQLException e
) {
211 if (connection
!= null && ! connection
.getAutoCommit()){
212 connection
.rollback();
214 }catch (SQLException ex
){
215 //do nothing - maybe throw RuntimeException in future
216 throw new RuntimeException(ex
);
218 logger
.error("Problems when executing update\n " + sqlUpdate
+ " \n" + "Exception: " + e
);
224 public void startTransaction() {
226 Connection connection
= getConnection();
227 this.connection
= connection
;
228 connection
.setAutoCommit(false);
230 } catch(SQLException e
) {
231 logger
.error("Problems when starting transaction \n" + "Exception: " + e
);
237 public void commitTransaction() throws SQLException
{
239 Connection connection
= getConnection();
241 } catch(SQLException e
) {
242 logger
.error("Problems when commiting transaction \n" + "Exception: " + e
);
248 public void rollback() throws SQLException
{
250 Connection connection
= getConnection();
251 connection
.rollback();
252 } catch(SQLException e
) {
253 logger
.error("Problems when rolling back transaction \n" + "Exception: " + e
);
260 public DatabaseMetaData
getMetaData() {
261 Connection connection
= null;
263 connection
= getConnection();
264 return connection
.getMetaData();
265 } catch (SQLException e
) {
266 logger
.error("Could not get metadata for datasource", e
);
272 public void closeOpenConnections() {
274 if(connection
!= null && !connection
.isClosed()){
278 } catch (SQLException e
) {
279 logger
.error("Error closing the connection");
283 // ************ javax.sql.DataSource base interfaces ********************/
287 public PrintWriter
getLogWriter() throws SQLException
{
288 //implementations copied from org.springframework.jdbc.datasource.AbstractDataSource;
289 throw new UnsupportedOperationException("getLogWriter");
294 public void setLogWriter(PrintWriter out
) throws SQLException
{
295 //implementations copied from org.springframework.jdbc.datasource.AbstractDataSource;
296 throw new UnsupportedOperationException("setLogWriter");
301 public void setLoginTimeout(int seconds
) throws SQLException
{
302 //implementations copied from org.springframework.jdbc.datasource.AbstractDataSource;
303 throw new UnsupportedOperationException("setLoginTimeout");
308 public int getLoginTimeout() throws SQLException
{
309 //implementations copied from org.springframework.jdbc.datasource.AbstractDataSource;
315 * This is a preliminary implementation to be compliant with
316 * java.sql.Datasource (1.6). It may not be fully working.
317 * Please let the developers know if this doesn't work.
320 //---------------------------------------------------------------------
321 // Implementation of JDBC 4.0's Wrapper interface
322 //---------------------------------------------------------------------
325 @SuppressWarnings("unchecked")
326 public <T
> T
unwrap(Class
<T
> iface
) throws SQLException
{
327 if (iface
.isInstance(this)) {
330 throw new SQLException("DataSource of type [" + getClass().getName() +
331 "] cannot be unwrapped as [" + iface
.getName() + "]");
335 public boolean isWrapperFor(Class
<?
> iface
) throws SQLException
{
336 return iface
.isInstance(this);
340 //---------------------------------------------------------------------
341 // Implementation of JDBC 4.1's getParentLogger method
342 // Required in Java >=7.x
343 // must not have the @Override annotation for compatibility with
345 //---------------------------------------------------------------------
347 public java
.util
.logging
.Logger
getParentLogger() {
348 //copied from org.springframework.jdbc.datasource.AbstractDataSource, not checked if this is correct
349 return java
.util
.logging
.Logger
.getLogger(java
.util
.logging
.Logger
.GLOBAL_LOGGER_NAME
);
353 public Map
<MetaDataPropertyName
, String
> getMetaDataMap() throws CdmSourceException
{
354 Map
<MetaDataPropertyName
, String
> cdmMetaDataMap
= new HashMap
<MetaDataPropertyName
, String
>();
356 for(MetaDataPropertyName mdpn
: MetaDataPropertyName
.values()) {
359 value
= (String
)getSingleValue(mdpn
.getSqlQuery());
360 } catch (SQLException e
) {
361 throw new CdmSourceException(e
.getMessage());
364 cdmMetaDataMap
.put(mdpn
, value
);
367 return cdmMetaDataMap
;