3 * Copyright (C) 2007 EDIT
4 * European Distributed Institute of Taxonomy
5 * http://www.e-taxonomy.eu
7 * The contents of this file are subject to the Mozilla Public License Version 1.1
8 * See LICENSE.TXT at the top of this package for the full license terms.
11 package eu
.etaxonomy
.cdm
.api
.service
;
13 import java
.sql
.Connection
;
14 import java
.sql
.ResultSet
;
15 import java
.sql
.SQLException
;
16 import java
.sql
.Statement
;
17 import java
.util
.HashMap
;
20 import javax
.sql
.DataSource
;
22 import org
.apache
.log4j
.Logger
;
23 import org
.hibernate
.SessionFactory
;
24 import org
.springframework
.beans
.BeansException
;
25 import org
.springframework
.beans
.factory
.annotation
.Autowired
;
26 import org
.springframework
.context
.ApplicationContext
;
27 import org
.springframework
.context
.ApplicationContextAware
;
28 import org
.springframework
.jdbc
.datasource
.AbstractDriverBasedDataSource
;
29 import org
.springframework
.orm
.hibernate4
.SessionFactoryUtils
;
30 import org
.springframework
.stereotype
.Service
;
31 import org
.springframework
.transaction
.annotation
.Transactional
;
33 import eu
.etaxonomy
.cdm
.api
.application
.CdmApplicationController
;
34 import eu
.etaxonomy
.cdm
.config
.CdmPersistentSourceUtils
;
35 import eu
.etaxonomy
.cdm
.config
.CdmSourceException
;
36 import eu
.etaxonomy
.cdm
.database
.CdmDataSource
;
37 import eu
.etaxonomy
.cdm
.database
.CdmPersistentDataSource
;
38 import eu
.etaxonomy
.cdm
.database
.DataSourceNotFoundException
;
39 import eu
.etaxonomy
.cdm
.database
.DatabaseTypeEnum
;
40 import eu
.etaxonomy
.cdm
.database
.H2Mode
;
41 import eu
.etaxonomy
.cdm
.database
.ICdmDataSource
;
42 import eu
.etaxonomy
.cdm
.model
.common
.init
.TermNotFoundException
;
43 import eu
.etaxonomy
.cdm
.model
.metadata
.CdmMetaData
.MetaDataPropertyName
;
44 import eu
.etaxonomy
.cdm
.model
.name
.NomenclaturalCode
;
49 * Implementation of service which provides functionality to directly access database
50 * related information.
56 @Transactional(readOnly
= true)
57 public class DatabaseServiceHibernateImpl
implements IDatabaseService
, ApplicationContextAware
{
58 private static final Logger logger
= Logger
.getLogger(DatabaseServiceHibernateImpl
.class);
60 private static final String TMP_DATASOURCE
= "tmp";
63 private SessionFactory factory
;
66 protected ApplicationContext appContext
;
68 private CdmApplicationController application
;
74 * @see eu.etaxonomy.cdm.api.service.IDatabaseService#setApplicationController(eu.etaxonomy.cdm.api.application.CdmApplicationController)
76 public void setApplicationController(CdmApplicationController cdmApplicationController
){
77 this.application
= cdmApplicationController
;
82 * @see eu.etaxonomy.cdm.api.service.IDatabaseService#connectToDatasource(eu.etaxonomy.cdm.database.CdmDataSource)
84 public boolean connectToDatasource(CdmPersistentDataSource dataSource
) throws TermNotFoundException
{
85 this.application
.changeDataSource(dataSource
);
86 logger
.debug("DataSource changed to " + dataSource
.getName());
91 * @see eu.etaxonomy.cdm.api.service.IDatabaseService#connectToDatabase(eu.etaxonomy.cdm.database.DatabaseTypeEnum, java.lang.String, java.lang.String, java.lang.String, java.lang.String, int)
93 public boolean connectToDatabase(DatabaseTypeEnum databaseTypeEnum
, String server
,
94 String database
, String username
, String password
, int port
, String filePath
, H2Mode mode
, NomenclaturalCode code
) throws TermNotFoundException
{
95 ICdmDataSource dataSource
= CdmDataSource
.NewInstance(databaseTypeEnum
, server
, database
, port
, username
, password
, code
);
96 CdmPersistentDataSource tmpDataSource
= saveDataSource(TMP_DATASOURCE
, dataSource
);
97 boolean result
= connectToDatasource(tmpDataSource
);
98 CdmPersistentSourceUtils
.delete(tmpDataSource
);
104 * @see eu.etaxonomy.cdm.api.service.IDatabaseService#connectToDatabase(eu.etaxonomy.cdm.database.DatabaseTypeEnum, java.lang.String, java.lang.String, java.lang.String, java.lang.String)
106 public boolean connectToDatabase(DatabaseTypeEnum databaseTypeEnum
, String server
,
107 String database
, String username
, String password
) throws TermNotFoundException
{
108 return connectToDatabase(databaseTypeEnum
, server
, database
, username
, password
, databaseTypeEnum
.getDefaultPort(), null, null, null) ;
112 * @see eu.etaxonomy.cdm.api.service.IDatabaseService#saveDataSource(java.lang.String, eu.etaxonomy.cdm.database.ICdmDataSource)
114 public CdmPersistentDataSource
saveDataSource(String strDataSourceName
,
115 ICdmDataSource dataSource
) {
116 return CdmPersistentDataSource
.save(strDataSourceName
, dataSource
);
120 * @see eu.etaxonomy.cdm.api.service.IDatabaseService#updateDataSource(java.lang.String, eu.etaxonomy.cdm.database.CdmPersistentDataSource)
122 public CdmPersistentDataSource
updateDataSource(String strDataSourceName
,
123 CdmPersistentDataSource dataSource
) throws DataSourceNotFoundException
{
124 return CdmPersistentDataSource
.update(strDataSourceName
, dataSource
);
128 * @see eu.etaxonomy.cdm.api.service.IDatabaseService#getUrl()
130 public String
getUrl() {
131 return getDataSource().getUrl();
135 * @see eu.etaxonomy.cdm.api.service.IDatabaseService#getUsername()
137 public String
getUsername() {
138 return getDataSource().getUsername();
142 * Returns the AbstractDriverBasedDataSource from hibernate,
143 * generalized in order to also allow using SimpleDriverDataSource.
145 * @return the AbstractDriverBasedDataSource from the hibernate layer
147 private AbstractDriverBasedDataSource
getDataSource(){
148 AbstractDriverBasedDataSource ds
= (AbstractDriverBasedDataSource
)SessionFactoryUtils
.getDataSource(factory
);
154 * @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.ApplicationContext)
156 public void setApplicationContext(ApplicationContext applicationContext
)
157 throws BeansException
{
158 this.appContext
= applicationContext
;
164 * @see eu.etaxonomy.cdm.api.service.IDatabaseService#getDbSchemaVersion()
167 public String
getDbSchemaVersion() throws CdmSourceException
{
169 return (String
)getSingleValue(MetaDataPropertyName
.DB_SCHEMA_VERSION
.getSqlQuery());
170 } catch (SQLException e
) {
171 throw new CdmSourceException(e
.getMessage());
177 * @see eu.etaxonomy.cdm.api.service.IDatabaseService#isDbEmpty()
180 public boolean isDbEmpty() throws CdmSourceException
{
181 // Any CDM DB should have a schema version
182 String dbSchemaVersion
= (String
) getDbSchemaVersion();
183 return (dbSchemaVersion
== null || dbSchemaVersion
.equals(""));
187 * Execute a SQL query which returns a single value
189 * @param query , which returns a single value
191 * @throws SQLException
193 private Object
getSingleValue(String query
) throws SQLException
{
194 String queryString
= query
== null?
"(null)": query
;
195 //ResultSet resultSet = executeQuery(query);
196 ResultSet resultSet
= null;
198 Connection connection
= SessionFactoryUtils
.getDataSource(factory
).getConnection();
199 if (connection
!= null){
201 Statement statement
= connection
.createStatement();
202 resultSet
= statement
.executeQuery(query
);
204 if (resultSet
== null || resultSet
.next() == false){
205 logger
.info("No record returned for query " + queryString
);
208 if (resultSet
.getMetaData().getColumnCount() != 1){
209 logger
.info("More than one column selected in query" + queryString
);
210 //first value will be taken
212 Object object
= resultSet
.getObject(1);
213 if (resultSet
.next()){
214 logger
.info("Multiple results for query " + queryString
);
215 //first row will be taken
217 // making sure we close all resources so we don't run out of
218 // connections in the connection pool
225 throw new RuntimeException("Could not establish connection to database");
232 public Map
<MetaDataPropertyName
, String
> getCdmMetadataMap() throws CdmSourceException
{
233 Map
<MetaDataPropertyName
, String
> cdmMetaDataMap
= new HashMap
<MetaDataPropertyName
, String
>();
235 for(MetaDataPropertyName mdpn
: MetaDataPropertyName
.values()){
238 value
= (String
)getSingleValue(mdpn
.getSqlQuery());
239 } catch (SQLException e
) {
240 throw new CdmSourceException(e
.getMessage());
243 cdmMetaDataMap
.put(mdpn
, value
);
246 return cdmMetaDataMap
;