Project

General

Profile

Download (13.9 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2007 EDIT
3
* European Distributed Institute of Taxonomy
4
* http://www.e-taxonomy.eu
5
*
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.
8
*/
9

    
10
package eu.etaxonomy.cdm.database;
11

    
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;
20
import java.util.Map;
21
import java.util.Properties;
22

    
23
import org.apache.logging.log4j.LogManager;import org.apache.logging.log4j.Logger;
24
import org.hibernate.cache.spi.RegionFactory;
25
import org.hibernate.envers.boot.internal.EnversIntegrator;
26
import org.springframework.beans.MutablePropertyValues;
27
import org.springframework.beans.factory.config.PropertiesFactoryBean;
28
import org.springframework.beans.factory.support.AbstractBeanDefinition;
29
import org.springframework.beans.factory.support.RootBeanDefinition;
30

    
31
import eu.etaxonomy.cdm.config.CdmSource;
32
import eu.etaxonomy.cdm.config.CdmSourceException;
33
import eu.etaxonomy.cdm.database.types.IDatabaseType;
34
import eu.etaxonomy.cdm.model.metadata.CdmMetaDataPropertyName;
35
import eu.etaxonomy.cdm.persistence.hibernate.HibernateConfiguration;
36

    
37
/**
38
 * @author a.mueller
39
 * @since 18.12.2008
40
 */
41
public abstract class CdmDataSourceBase extends CdmSource implements ICdmDataSource  {
42

    
43
    private static final Logger logger = LogManager.getLogger(CdmDataSourceBase.class);
44

    
45

    
46
    //	private static final int TIMEOUT = 10;
47
    private Connection connection;
48

    
49

    
50
    @Override
51
    public Connection getConnection() throws SQLException {
52
        return getConnection(getUsername(), getPassword());
53
    }
54

    
55

    
56
    @Override
57
    public Connection getConnection(String username, String password) throws SQLException {
58
        try {
59
            if(connection != null){
60
                boolean isValid = true;
61
//				try{
62
//					isValid = connection.isValid(TIMEOUT);
63
//				} catch (java.lang.AbstractMethodError e){
64
//					logger.error("Problems with Connection.isValid method\n" + "Exception: " + e.toString());
65
//				}
66
                if (isValid){
67
                    return connection;
68
                }
69
            }else{
70
                IDatabaseType dbType = getDatabaseType().getDatabaseType();
71
                String classString = dbType.getClassString();
72
                Class.forName(classString);
73
                String mUrl = dbType.getConnectionString(this);
74
                Connection connection = DriverManager.getConnection(mUrl, username, password);
75
                return 	connection;
76
            }
77
        } catch (ClassNotFoundException e) {
78
            throw new RuntimeException("Database driver class could not be loaded\n" + "Exception: " + e.toString(),e);
79
        } catch(SQLException e) {
80
            throw new RuntimeException("Problems with database connection\n" + "Exception: " + e.toString(), e);
81
        }
82
        return null;
83
    }
84

    
85
    @Override
86
    public boolean testConnection() throws ClassNotFoundException, SQLException {
87

    
88
        IDatabaseType dbType = getDatabaseType().getDatabaseType();
89
        String classString = dbType.getClassString();
90
        Class.forName(classString);
91
        String mUrl = dbType.getConnectionString(this);
92
        if(logger.isDebugEnabled()){
93
            logger.debug("testConnection() : " + mUrl);
94
        }
95

    
96
        if(logger.isDebugEnabled()){
97
            logger.debug("testConnection() : " + mUrl + " : service is available");
98
        }
99
        // try to connect to the database server
100
        Connection connection = DriverManager.getConnection(mUrl, getUsername(), getPassword());
101
        if (connection != null){
102
            if(logger.isDebugEnabled()){
103
                logger.debug("testConnection() : " + mUrl + " : jdbc connect successful");
104
            }
105
            return true;
106
        }
107

    
108
        if(logger.isDebugEnabled()){
109
            logger.debug("testConnection() : " + mUrl + " : FAIL");
110
        }
111
        return false;
112
    }
113

    
114
	@Override
115
	public boolean checkConnection() throws CdmSourceException {
116
		try {
117
			return testConnection();
118
		} catch (ClassNotFoundException e) {
119
			throw new CdmSourceException(e.getMessage());
120
		} catch (SQLException e) {
121
			throw new CdmSourceException(e.getMessage());
122
		}
123
	}
124

    
125
	@Override
126
	public String getConnectionMessage() {
127
		String message = "";
128
		if (getDatabaseType().equals(DatabaseTypeEnum.H2)) {
129
			message = " local CDM Store ";
130
		} else {
131
			message = " CDM Community Store ";
132
		}
133
		message += "'" + getName() + "'";
134

    
135
		message = "Connecting to" + message + ".";
136

    
137
		return message;
138
	}
139

    
140
    @Override
141
    public Object getSingleValue(String query) throws SQLException{
142
        String queryString = query == null? "(null)": query;
143
        ResultSet resultSet = executeQuery(query);
144
        if (resultSet == null || resultSet.next() == false){
145
            logger.info("No record returned for query " +  queryString);
146
            return null;
147
        }
148
        if (resultSet.getMetaData().getColumnCount() != 1){
149
            logger.info("More than one column selected in query" +  queryString);
150
            //first value will be taken
151
        }
152
        Object object = resultSet.getObject(1);
153
        if (resultSet.next()){
154
            logger.info("Multiple results for query " +  queryString);
155
            //first row will be taken
156
        }
157
        return object;
158
    }
159

    
160
	@Override
161
	public String getDbSchemaVersion() throws CdmSourceException  {
162
		try {
163
			return (String)getSingleValue(CdmMetaDataPropertyName.DB_SCHEMA_VERSION.getSqlQuery());
164
		} catch (SQLException e) {
165
		    try {
166
	            return (String)getSingleValue(CdmMetaDataPropertyName.DB_SCHEMA_VERSION.getSqlQueryOld());
167
	        } catch (SQLException e1) {
168
	            throw new CdmSourceException(e1.getMessage());
169
	        }
170
		}
171
	}
172

    
173
	@Override
174
	public boolean isDbEmpty() throws CdmSourceException {
175
		// Any CDM DB should have a schema version
176
		String dbSchemaVersion = getDbSchemaVersion();
177

    
178
		return (dbSchemaVersion == null || dbSchemaVersion.equals(""));
179
	}
180
    /**
181
     * Executes a query and returns the ResultSet.
182
     * @return ResultSet for the query.
183
     * @throws SQLException
184
     */
185
    @Override
186
    public ResultSet executeQuery (String query) throws SQLException {
187

    
188
        ResultSet resultSet;
189

    
190
        if (query == null){
191
            return null;
192
        }
193
        Connection connection = getConnection();
194
        if (connection != null){
195
            Statement statement = connection.createStatement();
196
            resultSet = statement.executeQuery(query);
197
        }else{
198
            throw new RuntimeException("Could not establish connection to database");
199
        }
200
        return resultSet;
201

    
202
    }
203

    
204
    @Override
205
    public int executeUpdate (String sqlUpdate) throws SQLException{
206

    
207
        int result;
208
        Connection connection = null;
209
        try {
210
            if (sqlUpdate == null){
211
                return 0;
212
            }
213
            connection = getConnection();
214
            Statement statement = connection.createStatement();
215
            result = statement.executeUpdate(sqlUpdate);
216
            return result;
217
        } catch(SQLException e) {
218
            try{
219
                if (connection != null && ! connection.getAutoCommit()){
220
                    connection.rollback();
221
                }
222
            }catch (SQLException ex){
223
                //do nothing -  maybe throw RuntimeException in future
224
                throw new RuntimeException(ex);
225
            }
226
            logger.error("Problems when executing update\n  " + sqlUpdate + " \n" + "Exception: " + e);
227
            throw e;
228
        }
229
    }
230

    
231
    @Override
232
    public void startTransaction() {
233
        try {
234
            Connection connection = getConnection();
235
            this.connection = connection;
236
            connection.setAutoCommit(false);
237
            return;
238
        } catch(SQLException e) {
239
            logger.error("Problems when starting transaction \n" + "Exception: " + e);
240
            return;
241
        }
242
    }
243

    
244
    @Override
245
    public void commitTransaction() throws SQLException {
246
        try {
247
            Connection connection = getConnection();
248
            connection.commit();
249
        } catch(SQLException e) {
250
            logger.error("Problems when commiting transaction \n" + "Exception: " + e);
251
            throw e;
252
        }
253
    }
254

    
255
    @Override
256
    public void rollback() throws SQLException {
257
        try {
258
            Connection connection = getConnection();
259
            connection.rollback();
260
        } catch(SQLException e) {
261
            logger.error("Problems when rolling back transaction \n" + "Exception: " + e);
262
            throw e;
263
        }
264
    }
265

    
266

    
267
    @Override
268
    public DatabaseMetaData getMetaData() {
269
        Connection connection = null;
270
        try {
271
            connection = getConnection();
272
            return connection.getMetaData();
273
        } catch (SQLException e) {
274
            logger.error("Could not get metadata for datasource", e);
275
            return null;
276
        }
277
    }
278

    
279
    @Override
280
    public void closeOpenConnections() {
281
        try {
282
            if(connection != null && !connection.isClosed()){
283
                connection.close();
284
                connection = null;
285
            }
286
        } catch (SQLException e) {
287
            logger.error("Error closing the connection");
288
        }
289
    }
290

    
291

    
292
    @Override
293
    public Map<CdmMetaDataPropertyName, String> getMetaDataMap() throws CdmSourceException {
294
		Map<CdmMetaDataPropertyName, String> cdmMetaDataMap = new HashMap<>();
295

    
296
		for(CdmMetaDataPropertyName mdpn : CdmMetaDataPropertyName.values()) {
297
			String value = null;
298
			try {
299
				value = (String)getSingleValue(mdpn.getSqlQuery());
300
			} catch (SQLException e1) {
301
			    try {
302
	                value = (String)getSingleValue(mdpn.getSqlQueryOld());
303
	            } catch (SQLException e) {
304
	                throw new CdmSourceException(this.toString(), e.getMessage());
305
	            }
306
			}
307
			if(value != null) {
308
				cdmMetaDataMap.put(mdpn, value);
309
			}
310
		}
311
		return cdmMetaDataMap;
312
    }
313

    
314
    // ************ javax.sql.DataSource base interfaces ********************/
315

    
316

    
317
    @Override
318
    public PrintWriter getLogWriter() throws SQLException {
319
        //implementations copied from org.springframework.jdbc.datasource.AbstractDataSource;
320
        throw new UnsupportedOperationException("getLogWriter");
321
    }
322

    
323

    
324
    @Override
325
    public void setLogWriter(PrintWriter out) throws SQLException {
326
        //implementations copied from org.springframework.jdbc.datasource.AbstractDataSource;
327
        throw new UnsupportedOperationException("setLogWriter");
328
    }
329

    
330

    
331
    @Override
332
    public void setLoginTimeout(int seconds) throws SQLException {
333
        //implementations copied from org.springframework.jdbc.datasource.AbstractDataSource;
334
        throw new UnsupportedOperationException("setLoginTimeout");
335
    }
336

    
337

    
338
    @Override
339
    public int getLoginTimeout() throws SQLException {
340
        //implementations copied from org.springframework.jdbc.datasource.AbstractDataSource;
341
        return 0;
342
    }
343

    
344

    
345
    /*
346
     * This is a preliminary implementation to be compliant with
347
     * java.sql.Datasource (1.6). It may not be fully working.
348
     * Please let the developers know if this doesn't work.
349
     */
350

    
351
    //---------------------------------------------------------------------
352
    // Implementation of JDBC 4.0's Wrapper interface
353
    //---------------------------------------------------------------------
354

    
355
    @Override
356
    @SuppressWarnings("unchecked")
357
    public <T> T unwrap(Class<T> iface) throws SQLException {
358
        if (iface.isInstance(this)) {
359
            return (T) this;
360
        }
361
        throw new SQLException("DataSource of type [" + getClass().getName() +
362
                "] cannot be unwrapped as [" + iface.getName() + "]");
363
    }
364

    
365
    @Override
366
    public boolean isWrapperFor(Class<?> iface) throws SQLException {
367
        return iface.isInstance(this);
368
    }
369

    
370

    
371
    //---------------------------------------------------------------------
372
    // Implementation of JDBC 4.1's getParentLogger method
373
    // Required in Java >=7.x
374
    // must not have the @Override annotation for compatibility with
375
    // java 1.6
376
    //---------------------------------------------------------------------
377
    @Override
378
    public java.util.logging.Logger getParentLogger() {
379
        //copied from org.springframework.jdbc.datasource.AbstractDataSource, not checked if this is correct
380
        return java.util.logging.Logger.getLogger(java.util.logging.Logger.GLOBAL_LOGGER_NAME);
381
    }
382

    
383
    //********************* Base methods for CdmDataSource and CdmPersistentDatasource
384

    
385
    protected AbstractBeanDefinition makeHibernatePropertiesBean(DatabaseTypeEnum dbType,
386
            DbSchemaValidation hbm2dll, boolean showSql,
387
            boolean formatSql, boolean registerAuditing, boolean registerSearchListener,
388
            Class<? extends RegionFactory> cacheProviderClass,
389
            String byteCodeProvider) {
390

    
391
        AbstractBeanDefinition bd = new RootBeanDefinition(PropertiesFactoryBean.class);
392
        MutablePropertyValues hibernateProps = new MutablePropertyValues();
393

    
394
        Properties props = new Properties();
395
        props.setProperty("hibernate.hbm2ddl.auto", hbm2dll.toString());
396
        props.setProperty("hibernate.dialect", dbType.getHibernateDialectCanonicalName());
397
//      OLD:props.setProperty("hibernate.cache.provider_class", cacheProviderClass.getName());
398
        props.setProperty(HibernateConfiguration.CACHE_PROVIDER_CLASS, cacheProviderClass.getName());
399
        props.setProperty(HibernateConfiguration.SHOW_SQL, String.valueOf(showSql));
400
        props.setProperty(HibernateConfiguration.FORMAT_SQL, String.valueOf(formatSql));
401
        props.setProperty(HibernateConfiguration.REGISTER_SEARCH, String.valueOf(registerSearchListener));
402
        props.setProperty(EnversIntegrator.AUTO_REGISTER, String.valueOf(registerAuditing));
403
        props.setProperty(HibernateConfiguration.BYTECODE_PROVIDER, byteCodeProvider);
404

    
405
        hibernateProps.add("properties",props);
406
        bd.setPropertyValues(hibernateProps);
407
        return bd;
408

    
409
    }
410

    
411

    
412
}
(2-2/21)