add unknownData to structured descriptive data #2975
[cdmlib.git] / cdmlib-persistence / src / main / java / eu / etaxonomy / cdm / database / CdmDataSourceBase.java
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
20 import org.apache.log4j.Logger;
21
22 import eu.etaxonomy.cdm.database.types.IDatabaseType;
23
24 /**
25 * @author a.mueller
26 * @created 18.12.2008
27 * @veresultSetion 1.0
28 */
29 abstract class CdmDataSourceBase implements ICdmDataSource {
30
31
32 private static final Logger logger = Logger.getLogger(CdmDataSourceBase.class);
33
34
35 // private static final int TIMEOUT = 10;
36 private Connection connection;
37
38
39 @Override
40 public Connection getConnection() throws SQLException {
41 return getConnection(getUsername(), getPassword());
42 }
43
44
45 @Override
46 public Connection getConnection(String username, String password) throws SQLException {
47 try {
48 if(connection != null){
49 boolean isValid = true;
50 // try{
51 // isValid = connection.isValid(TIMEOUT);
52 // } catch (java.lang.AbstractMethodError e){
53 // logger.error("Problems with Connection.isValid method\n" + "Exception: " + e.toString());
54 // }
55 if (isValid){
56 return connection;
57 }
58 }else{
59 IDatabaseType dbType = getDatabaseType().getDatabaseType();
60 String classString = dbType.getClassString();
61 Class.forName(classString);
62 String mUrl = dbType.getConnectionString(this);
63 Connection connection = DriverManager.getConnection(mUrl, username, password);
64 return connection;
65 }
66 } catch (ClassNotFoundException e) {
67 throw new RuntimeException("Database driver class could not be loaded\n" + "Exception: " + e.toString(),e);
68 } catch(SQLException e) {
69 throw new RuntimeException("Problems with database connection\n" + "Exception: " + e.toString(), e);
70 }
71 return null;
72 }
73
74
75 /* (non-Javadoc)
76 * @see eu.etaxonomy.cdm.database.ICdmDataSource#testConnection()
77 */
78 @Override
79 public boolean testConnection() throws ClassNotFoundException, SQLException {
80
81 IDatabaseType dbType = getDatabaseType().getDatabaseType();
82 String classString = dbType.getClassString();
83 Class.forName(classString);
84 String mUrl = dbType.getConnectionString(this);
85 Connection connection = DriverManager.getConnection(mUrl, getUsername(), getPassword());
86 if (connection != null){
87 return true;
88 }
89
90 return false;
91 }
92
93 @Override
94 public Object getSingleValue(String query) throws SQLException{
95 String queryString = query == null? "(null)": query;
96 ResultSet resultSet = executeQuery(query);
97 if (resultSet == null || resultSet.next() == false){
98 logger.info("No record returned for query " + queryString);
99 return null;
100 }
101 if (resultSet.getMetaData().getColumnCount() != 1){
102 logger.info("More than one column selected in query" + queryString);
103 //first value will be taken
104 }
105 Object object = resultSet.getObject(1);
106 if (resultSet.next()){
107 logger.info("Multiple results for query " + queryString);
108 //first row will be taken
109 }
110 return object;
111 }
112
113
114 /**
115 * Executes a query and returns the ResultSet.
116 * @return ResultSet for the query.
117 * @throws SQLException
118 */
119 @Override
120 public ResultSet executeQuery (String query) throws SQLException {
121
122 ResultSet resultSet;
123
124 if (query == null){
125 return null;
126 }
127 Connection connection = getConnection();
128 if (connection != null){
129 Statement statement = connection.createStatement();
130 resultSet = statement.executeQuery(query);
131 }else{
132 throw new RuntimeException("Could not establish connection to database");
133 }
134 return resultSet;
135
136 }
137
138
139 /* (non-Javadoc)
140 * @see eu.etaxonomy.cdm.database.ICdmDataSource#executeUpdate(java.lang.String)
141 */
142 @Override
143 public int executeUpdate (String sqlUpdate) throws SQLException{
144
145 int result;
146 Connection connection = null;
147 try {
148 if (sqlUpdate == null){
149 return 0;
150 }
151 connection = getConnection();
152 Statement statement = connection.createStatement();
153 result = statement.executeUpdate(sqlUpdate);
154 return result;
155 } catch(SQLException e) {
156 try{
157 if (! connection.getAutoCommit()){
158 connection.rollback();
159 }
160 }catch (SQLException ex){
161 //do nothing - maybe throw RuntimeException in future
162 throw new RuntimeException(ex);
163 }
164 logger.error("Problems when executing update\n " + sqlUpdate + " \n" + "Exception: " + e);
165 throw e;
166 }
167 }
168
169
170 /* (non-Javadoc)
171 * @see eu.etaxonomy.cdm.database.ICdmDataSource#startTransaction()
172 */
173 @Override
174 public void startTransaction() {
175 try {
176 Connection connection = getConnection();
177 this.connection = connection;
178 connection.setAutoCommit(false);
179 return;
180 } catch(SQLException e) {
181 logger.error("Problems when starting transaction \n" + "Exception: " + e);
182 return;
183 }
184 }
185
186 /* (non-Javadoc)
187 * @see eu.etaxonomy.cdm.database.ICdmDataSource#commitTransaction()
188 */
189 @Override
190 public void commitTransaction() throws SQLException {
191 try {
192 Connection connection = getConnection();
193 connection.commit();
194 } catch(SQLException e) {
195 logger.error("Problems when commiting transaction \n" + "Exception: " + e);
196 throw e;
197 }
198 }
199
200 @Override
201 public void rollback() throws SQLException {
202 try {
203 Connection connection = getConnection();
204 connection.rollback();
205 } catch(SQLException e) {
206 logger.error("Problems when rolling back transaction \n" + "Exception: " + e);
207 throw e;
208 }
209 }
210
211 /* (non-Javadoc)
212 * @see eu.etaxonomy.cdm.database.ICdmDataSource#getMetaData()
213 */
214 @Override
215 public DatabaseMetaData getMetaData() {
216 Connection connection = null;
217 try {
218 connection = getConnection();
219 return connection.getMetaData();
220 } catch (SQLException e) {
221 logger.error("Could not get metadata for datasource", e);
222 return null;
223 }
224 }
225
226 /* (non-Javadoc)
227 * @see eu.etaxonomy.cdm.database.ICdmDataSource#closeOpenConnections()
228 */
229 @Override
230 public void closeOpenConnections() {
231 try {
232 if(connection != null && !connection.isClosed()){
233 connection.close();
234 connection = null;
235 }
236 } catch (SQLException e) {
237 logger.error("Error closing the connection");
238 }
239 }
240
241 // ************ javax.sql.DataSource base interfaces ********************/
242
243
244 @Override
245 public PrintWriter getLogWriter() throws SQLException {
246 //implementations copied from org.springframework.jdbc.datasource.AbstractDataSource;
247 throw new UnsupportedOperationException("getLogWriter");
248 }
249
250
251 @Override
252 public void setLogWriter(PrintWriter out) throws SQLException {
253 //implementations copied from org.springframework.jdbc.datasource.AbstractDataSource;
254 throw new UnsupportedOperationException("setLogWriter");
255 }
256
257
258 @Override
259 public void setLoginTimeout(int seconds) throws SQLException {
260 //implementations copied from org.springframework.jdbc.datasource.AbstractDataSource;
261 throw new UnsupportedOperationException("setLoginTimeout");
262 }
263
264
265 @Override
266 public int getLoginTimeout() throws SQLException {
267 //implementations copied from org.springframework.jdbc.datasource.AbstractDataSource;
268 return 0;
269 }
270
271
272 /*
273 * This is a preliminary implementation to be compliant with
274 * java.sql.Datasource (1.6). It may not be fully working.
275 * Please let the developers know if this doesn't work.
276 */
277
278 //---------------------------------------------------------------------
279 // Implementation of JDBC 4.0's Wrapper interface
280 //---------------------------------------------------------------------
281
282 @Override
283 @SuppressWarnings("unchecked")
284 public <T> T unwrap(Class<T> iface) throws SQLException {
285 if (iface.isInstance(this)) {
286 return (T) this;
287 }
288 throw new SQLException("DataSource of type [" + getClass().getName() +
289 "] cannot be unwrapped as [" + iface.getName() + "]");
290 }
291
292 @Override
293 public boolean isWrapperFor(Class<?> iface) throws SQLException {
294 return iface.isInstance(this);
295 }
296
297
298 //---------------------------------------------------------------------
299 // Implementation of JDBC 4.1's getParentLogger method
300 // Required in Java >=7.x
301 // must not have the @Override annotation for compatibility with
302 // java 1.6
303 //---------------------------------------------------------------------
304
305 public java.util.logging.Logger getParentLogger() {
306 //copied from org.springframework.jdbc.datasource.AbstractDataSource, not checked if this is correct
307 return java.util.logging.Logger.getLogger(java.util.logging.Logger.GLOBAL_LOGGER_NAME);
308 }
309
310 }