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 Version 1.1
7 * See LICENSE.TXT at the top of this package for the full license terms.
10 package eu
.etaxonomy
.cdm
.api
.service
;
12 import java
.sql
.Connection
;
13 import java
.sql
.ResultSet
;
14 import java
.sql
.SQLException
;
15 import java
.sql
.Statement
;
16 import java
.util
.HashMap
;
19 import org
.apache
.log4j
.Logger
;
20 import org
.hibernate
.SessionFactory
;
21 import org
.springframework
.beans
.BeansException
;
22 import org
.springframework
.beans
.factory
.annotation
.Autowired
;
23 import org
.springframework
.context
.ApplicationContext
;
24 import org
.springframework
.context
.ApplicationContextAware
;
25 import org
.springframework
.jdbc
.datasource
.AbstractDriverBasedDataSource
;
26 import org
.springframework
.orm
.hibernate5
.SessionFactoryUtils
;
27 import org
.springframework
.stereotype
.Service
;
28 import org
.springframework
.transaction
.annotation
.Transactional
;
30 import eu
.etaxonomy
.cdm
.api
.application
.CdmApplicationController
;
31 import eu
.etaxonomy
.cdm
.config
.CdmPersistentSourceUtils
;
32 import eu
.etaxonomy
.cdm
.config
.CdmSourceException
;
33 import eu
.etaxonomy
.cdm
.database
.CdmDataSource
;
34 import eu
.etaxonomy
.cdm
.database
.CdmPersistentDataSource
;
35 import eu
.etaxonomy
.cdm
.database
.DataSourceNotFoundException
;
36 import eu
.etaxonomy
.cdm
.database
.DatabaseTypeEnum
;
37 import eu
.etaxonomy
.cdm
.database
.H2Mode
;
38 import eu
.etaxonomy
.cdm
.database
.ICdmDataSource
;
39 import eu
.etaxonomy
.cdm
.model
.metadata
.CdmMetaDataPropertyName
;
40 import eu
.etaxonomy
.cdm
.model
.term
.init
.TermNotFoundException
;
45 * Implementation of service which provides functionality to directly access database
46 * related information.
52 @Transactional(readOnly
= true)
53 public class DatabaseServiceHibernateImpl
implements IDatabaseService
, ApplicationContextAware
{
54 private static final Logger logger
= Logger
.getLogger(DatabaseServiceHibernateImpl
.class);
56 private static final String TMP_DATASOURCE
= "tmp";
59 private SessionFactory factory
;
62 protected ApplicationContext appContext
;
64 private CdmApplicationController application
;
67 public void setApplicationController(CdmApplicationController cdmApplicationController
){
68 this.application
= cdmApplicationController
;
72 public boolean connectToDatasource(CdmPersistentDataSource dataSource
) throws TermNotFoundException
{
73 this.application
.changeDataSource(dataSource
);
74 logger
.debug("DataSource changed to " + dataSource
.getName());
79 public boolean connectToDatabase(DatabaseTypeEnum databaseTypeEnum
, String server
,
80 String database
, String username
, String password
, int port
, String filePath
, H2Mode mode
) throws TermNotFoundException
{
81 ICdmDataSource dataSource
= CdmDataSource
.NewInstance(databaseTypeEnum
, server
, database
, port
, username
, password
);
82 CdmPersistentDataSource tmpDataSource
= saveDataSource(TMP_DATASOURCE
, dataSource
);
83 boolean result
= connectToDatasource(tmpDataSource
);
84 CdmPersistentSourceUtils
.delete(tmpDataSource
);
89 public boolean connectToDatabase(DatabaseTypeEnum databaseTypeEnum
, String server
,
90 String database
, String username
, String password
) throws TermNotFoundException
{
91 return connectToDatabase(databaseTypeEnum
, server
, database
, username
, password
, databaseTypeEnum
.getDefaultPort(), null, null) ;
95 public CdmPersistentDataSource
saveDataSource(String strDataSourceName
,
96 ICdmDataSource dataSource
) {
97 return CdmPersistentDataSource
.save(strDataSourceName
, dataSource
);
101 public CdmPersistentDataSource
updateDataSource(String strDataSourceName
,
102 CdmPersistentDataSource dataSource
) throws DataSourceNotFoundException
{
103 return CdmPersistentDataSource
.update(strDataSourceName
, dataSource
);
107 public String
getUrl() {
108 return getDataSource().getUrl();
112 public String
getUsername() {
113 return getDataSource().getUsername();
117 * Returns the AbstractDriverBasedDataSource from hibernate,
118 * generalized in order to also allow using SimpleDriverDataSource.
120 * @return the AbstractDriverBasedDataSource from the hibernate layer
122 private AbstractDriverBasedDataSource
getDataSource(){
123 AbstractDriverBasedDataSource ds
= (AbstractDriverBasedDataSource
)SessionFactoryUtils
.getDataSource(factory
);
128 public void setApplicationContext(ApplicationContext applicationContext
)
129 throws BeansException
{
130 this.appContext
= applicationContext
;
134 public String
getDbSchemaVersion() throws CdmSourceException
{
136 return (String
)getSingleValue(CdmMetaDataPropertyName
.DB_SCHEMA_VERSION
.getSqlQuery());
137 } catch (SQLException e1
) {
139 return (String
)getSingleValue(CdmMetaDataPropertyName
.DB_SCHEMA_VERSION
.getSqlQueryOld());
140 } catch (SQLException e
) {
141 throw new CdmSourceException(e
.getMessage());
147 public boolean isDbEmpty() throws CdmSourceException
{
148 // Any CDM DB should have a schema version
149 String dbSchemaVersion
= getDbSchemaVersion();
150 return (dbSchemaVersion
== null || dbSchemaVersion
.equals(""));
154 * Execute a SQL query which returns a single value
156 * @param query , which returns a single value
158 * @throws SQLException
160 private Object
getSingleValue(String query
) throws SQLException
{
161 String queryString
= query
== null?
"(null)": query
;
162 //ResultSet resultSet = executeQuery(query);
163 ResultSet resultSet
= null;
165 Connection connection
= SessionFactoryUtils
.getDataSource(factory
).getConnection();
166 if (connection
!= null){
168 Statement statement
= connection
.createStatement();
169 resultSet
= statement
.executeQuery(query
);
171 if (resultSet
== null || resultSet
.next() == false){
172 logger
.info("No record returned for query " + queryString
);
175 if (resultSet
.getMetaData().getColumnCount() != 1){
176 logger
.info("More than one column selected in query" + queryString
);
177 //first value will be taken
179 Object object
= resultSet
.getObject(1);
180 if (resultSet
.next()){
181 logger
.info("Multiple results for query " + queryString
);
182 //first row will be taken
184 // making sure we close all resources so we don't run out of
185 // connections in the connection pool
192 throw new RuntimeException("Could not establish connection to database");
199 public Map
<CdmMetaDataPropertyName
, String
> getCdmMetadataMap() throws CdmSourceException
{
200 Map
<CdmMetaDataPropertyName
, String
> cdmMetaDataMap
= new HashMap
<>();
202 for(CdmMetaDataPropertyName mdpn
: CdmMetaDataPropertyName
.values()){
205 value
= (String
)getSingleValue(mdpn
.getSqlQuery());
206 } catch (SQLException e1
) {
208 value
= (String
)getSingleValue(mdpn
.getSqlQueryOld());
209 } catch (SQLException e
) {
210 throw new CdmSourceException(e
.getMessage());
214 cdmMetaDataMap
.put(mdpn
, value
);
217 return cdmMetaDataMap
;