Project

General

Profile

Download (15.3 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2009 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 Version 1.1
7
* See LICENSE.TXT at the top of this package for the full license terms.
8
*/ 
9

    
10
package eu.etaxonomy.cdm.io.common;
11

    
12
/*
13
 * Created on 14.05.2005
14
 * @author Andreas M�ller
15
 * Updated 20.08.2006
16
 */
17

    
18

    
19
import java.sql.*;
20
import java.io.*;
21

    
22
import javax.mail.MethodNotSupportedException;
23

    
24
import org.apache.log4j.Logger;
25

    
26
import eu.etaxonomy.cdm.database.ICdmDataSource;
27

    
28

    
29
/**
30
 *  
31
 *  Creates Cursors from extern relational DB.
32
 *  Used only for developpers convienence hence undocumented.
33
 *  You may create input cursors in any other way you want
34
 *  @author Andreas Müller
35
 */
36
public class Source {
37
	static Logger logger = Logger.getLogger(Source.class);
38

    
39
/* ************ Constants **************************************/
40
    //Mode
41
	private final static boolean DEBUG_MODE = false;
42
    private final static boolean DEBUG_LOG_WRITER = false;
43
	
44
    //DB info
45
//	public final static String SQL_SERVER_2000 = "SQLServer2000";
46
	public final static String SQL_SERVER_2005 = "SQLServer2005";
47
	public final static String SQL_SERVER_2008 = "SQLServer2008";
48
	public final static String ACCESS = "Access";
49
	public final static String EXCEL = "Excel";
50
	public final static String ODDBC = "ODBC";
51
	public final static String ORACLE = "Oracle";
52
	public final static String DB2 = "DB2";
53
	
54
	//coursor mode
55
	public final static String SELECT_DIRECT = "direct";
56
	public final static String SELECT_CURSOR = "cursor";
57
		
58
    //driver class
59
//    private static String clsSQLServer2000 = "com.microsoft.jdbc.sqlserver.SQLServerDriver";
60
    private static String clsSQLServer2005 = "com.microsoft.sqlserver.jdbc.SQLServerDriver";
61
    private static String clsSQLServer2008 = "com.microsoft.sqlserver.jdbc.SQLServerDriver";
62
    private static String clsODBC = "sun.jdbc.odbc.JdbcOdbcDriver";
63
    private static String clsOracle = "oracle.jdbc.driver.OracleDriver";
64
    private static String clsDB2 = "COM.ibm.db2.jdbc.net.DB2Driver";
65
    private static String clsSQLServerDdtek = "com.ddtek.jdbc.sqlserver.SQLServerDriver";
66
    private static String clsDefault = "com.microsoft.jdbc.sqlserver.SQLServerDriver";
67
    
68
    //url
69
//    private static String urlSQLServer = "jdbc:microsoft:sqlserver://";
70
    private static String urlSQLServer2005 = "jdbc:sqlserver://";
71
    private static String urlSQLServer2008 = "jdbc:sqlserver://";
72
    private static String urlDB2 = "jdbc:db2://";
73
    private static String urlOracle = "jdbc:oracle:thin:@:1243:";
74
    private static String urlDataDirectSQLServer = "jdbc:datadirect:sqlserver://";
75
    private static String urlODBC = "jdbc:odbc:";
76
    // FIXME this default is not acceptable
77
    private static String urlDefault = "jdbc:microsoft:sqlserver://LAPI:1433;DatabaseName=studienarbeit;SelectMethod=direct";
78
    
79
    
80
/* *************** VARIABLES *******************************/
81
    private Connection mConn;
82
    private Statement mStmt;
83
    private String mQuery;
84
    private String mUrl = null;
85
    private String mDb = null; 
86
    private int mPort = 1433; //default port TODO 2 derzeit nur f�r SQLServer, m�sste auch f�r andere Datenbanken umgesetzt werden
87
    private String mDbms = null;
88
    private String mServer = null;
89
    private boolean isCursor;
90
    private boolean connExist = false; //does a Connection exist?
91
    private String mUserName; 
92
    private String mPwd;
93

    
94
	private boolean doLog = false; 
95

    
96

    
97
	private static String userNameDefault = "sa"; //default user
98
    private static String pwdDefault = "sa"; //default PWD
99
    
100
    
101
/* ******************** CONSTRUCTORS **********************************/
102
    
103
    
104
    /**
105
     * Creates a source and sets the according variables
106
     * @param dbms name of database management system (e.g. "SQLServer", "Access", "Excel", "Oracle"
107
	 * @param server name of server, if dbms is ODBC, this must be the ODBC name
108
	 * @param db name of database
109
	*/
110
    public Source(String dbms, String server, String db){
111
    	mDbms = dbms;
112
        mServer = server;
113
        mDb = db;
114
        this.mPwd = pwdDefault;
115
        this.mUserName = userNameDefault;
116
    }
117

    
118
    /**
119
     * Creates a source and sets the query string
120
     * @param dbms name of database management system (e.g. "SQLServer", "Access", "Excel", "Oracle"
121
	 * @param server name of server, if dbms is ODBC, this must be the ODBC name
122
	 * @param db name of database
123
     * @param query the query
124
     */
125
    public Source(String dbms, String server, String db, String query){
126
        this(dbms, server, db);
127
        this.setQuery(query);
128
    }
129

    
130
    /**
131
    * Creates a source and sets the parameter.
132
     * @param cursor access mode, if true 'cursor', if false 'direct'
133
    */
134
    public Source(String dbms, String server, String db, boolean cursor)   {
135
        this(dbms, server, db);
136
    	isCursor = cursor;
137
    }
138
    
139

    
140
    /**
141
    * Creates a source and sets the parameter. If port is -1 the databases default port is used.
142
    * @param dbms name of database management system (e.g. "SQLServer", "Access", "Excel", "Oracle"
143
    * @param server name of server, if dbms is ODBC, this must be the ODBC name
144
    * @param db name of database
145
    * @param port the databases port (-1: use default port)
146
    */
147
    public Source(String dbms, String server, String db, int port) {
148
        this(dbms, server, db);
149
        if (port != -1){
150
        	this.setPort(port);
151
        };
152
    }
153
    
154
    /**
155
     * Creates a source with parameters of a ICdmDataSource instance
156
     * 
157
     * @param cdmDataSource
158
     */
159
    public Source(ICdmDataSource cdmDataSource){
160
    	mDbms = cdmDataSource.getDatabaseType().getName();
161
        mServer = cdmDataSource.getServer();
162
        mDb = cdmDataSource.getDatabase();
163
        mPwd = cdmDataSource.getPassword();
164
        mUserName = cdmDataSource.getUsername();
165
        this.setPort(cdmDataSource.getPort());
166
    }
167
    
168
//********************* METHODS *****************************************************/
169
   
170
    //******* RESULTSETS *******************//
171
    /**
172
     * Returns the Resultset for query 'query'. 
173
     * Does not change the Sources query-string!!
174
     * @return Resultset for the query.
175
     */
176
    public ResultSet getResultSet (String query){
177
    	ResultSet rs;
178
    	try {
179
            this.getConnection(); //establish connection
180
        	if (query == null){
181
        		return null;
182
        	}
183
            mStmt = mConn.createStatement();
184
            rs = mStmt.executeQuery(query);
185
            return rs;
186
        }catch(SQLException e){
187
            logger.error("Problems when creating Resultset for query \n  " + query + " \n" + "Exception: " + e);
188
            return null;
189
        }
190
    }
191

    
192
    //******* INSERT, UPDATE, DELETE *******************//
193
    /**
194
     * Executes an insert, update or delete statement.
195
     * Returns the number of rows changed or -1 if updatedStatement was 0 or and error occurred. 
196
     * Does not change the Sources query-string!!
197
     * @return Resultset for the query.
198
     */
199
    public int update (String updateStatement){
200
    	int result;
201
    	try {
202
            this.getConnection(); //establish connection
203
        	if (updateStatement == null){
204
        		return -1;
205
        	}
206
            mStmt = mConn.createStatement();
207
            result = mStmt.executeUpdate(updateStatement);
208
            return result;
209
        }catch(SQLException e){
210
            logger.error("Problems when creating Resultset for query \n  " + updateStatement + " \n" + "Exception: " + e);
211
            return -1;
212
        }
213
    }
214

    
215
    
216
    /** 
217
     * Returns the Resultset for Sources query. 
218
     * @return Resultset for the Sources query
219
     */
220
    public ResultSet getResultSet (){
221
    	return getResultSet(mQuery);  
222
    }
223

    
224
    
225
    // ***************CONNECTION *************************************//
226
    /**
227
     * Returns the connection.
228
     * @return the Sources connection
229
     */
230
    public Connection getConnection(){
231
    	try {
232
			if (this.connExist == false){
233
				if (mConn != null){ 
234
					mConn.close();
235
				}
236
				this.makeConnection() ;
237
    		}
238
			return this.mConn;
239
		} catch (SourceConnectionException e) {
240
			//TODO error weitergabe des Fehlers nach oben?
241
			logger.error("Error when establishing Connection");
242
			return null;
243
		} catch (SQLException e) {
244
			logger.error("SQLException in getConnection.");
245
			return null;
246
		}
247
    }
248
    
249
    
250
    /**
251
     * Makes the connection.
252
     * @return true if connection created
253
     * @throws SourceConnectionException
254
     */
255
    private boolean makeConnection()throws SourceConnectionException {
256
    	if (doLog ){
257
    		DriverManager.setLogWriter(new PrintWriter(System.out));
258
    	}
259
    	try {
260
			if (makeConnectionString() == false){
261
				throw new SourceConnectionException ("Error in Connection String");
262
			}
263
			if (mDbms.equalsIgnoreCase(ODDBC) ){
264
				//not necessarily limited to ODBC
265
				java.util.Properties prop = new java.util.Properties();
266
//			    prop.put("charSet", "Big5");
267
			    prop.put("user", mUserName);
268
			    prop.put("password", mPwd);
269
//			    DriverManager.setLogWriter(new PrintWriter(System.out));
270
			    mConn = DriverManager.getConnection(mUrl, prop);
271
			}else{
272
				mConn = DriverManager.getConnection(mUrl, mUserName, mPwd);				
273
			}
274

    
275
			
276
			
277
			mConn.setCatalog(mDb);  //
278
			logger.info("Connected to " + mConn.getCatalog());
279
			mStmt = mConn.createStatement();
280
			this.connExist = true;
281
			return true;
282
		}catch (SQLException e){
283
            logger.error("Problems when trying to open the database !!!\n" + 
284
                    "URL: " + mUrl  + "\n" +
285
                    "Exception: " + e);
286
            throw new SourceConnectionException ();
287
        } 
288
    }
289
    
290
    /**
291
     * Makes the connection string 
292
     * @return false if ClassNotFoundException, else true
293
     */
294
    private boolean makeConnectionString(){
295
    	String selectMethod; 
296
        String server;
297
        
298
    	if (isCursor)
299
	    	selectMethod = SELECT_CURSOR;
300
	    else
301
	    	selectMethod = SELECT_DIRECT;
302
	    try{
303
	        if (DEBUG_LOG_WRITER) DriverManager.setLogWriter((new PrintWriter(System.out)));
304
//	        if (mDbms.equalsIgnoreCase(SQL_SERVER_2000)) {
305
//	            Class.forName(clsSQLServer2000);
306
//	            server = mServer + ":" + mPort;
307
//	            mUrl = urlSQLServer + server + ";DataBase=" + mDb + ";SelectMethod="+ selectMethod; 
308
//	        }
309
	        else if (mDbms.equalsIgnoreCase(SQL_SERVER_2005)) {
310
	            Class.forName(clsSQLServer2005);
311
	            server = mServer + ":" + mPort;
312
	            mUrl = urlSQLServer2005 + server + ";databaseName=" + mDb +";SelectMethod="+ selectMethod; 
313
	        }
314
	        else if (mDbms.equalsIgnoreCase(SQL_SERVER_2008)) {
315
	            Class.forName(clsSQLServer2008);
316
	            server = mServer + ":" + mPort;
317
	            mUrl = urlSQLServer2008 + server + ";databaseName=" + mDb +";SelectMethod="+ selectMethod; 
318
	        }
319
	        else if (mDbms.equalsIgnoreCase(ACCESS)) {
320
	        	Class.forName(clsODBC);
321
	            
322
	        	//mDb must be the file path
323
	        	mUrl = urlODBC + "Driver={Microsoft Access Driver (*.mdb)};DBQ=";
324
	        	mUrl += mDb.trim() + ";DriverID=22;READONLY=false}";  
325
	        }
326
	        else if (mDbms.equalsIgnoreCase(EXCEL)) {
327
	            Class.forName(clsODBC);
328
	            mUrl = urlODBC + "jdbc:odbc:Driver={Microsoft Excel Driver (*.xls)};DBQ=";
329
	            mUrl += mDb.trim() + ";DriverID=22;READONLY=false";
330
	        }
331
	        else if (mDbms.equalsIgnoreCase(ODDBC)) {
332
	            //mDb must be the System DNS name
333
	        	Class.forName(clsODBC);
334
	            mUrl = urlODBC + mDb ; 
335
	        }
336
	        else if (mDbms.equalsIgnoreCase(ORACLE)) {
337
	            Class.forName(clsOracle);
338
	            mUrl = urlOracle + mDb ;
339
	        }
340
	        else if (mDbms.equalsIgnoreCase(DB2)) {
341
	            Class.forName(clsDB2);
342
	            mUrl = urlDB2 + mDb; 
343
	        }
344
	        else if (mDbms.equalsIgnoreCase("SQLServerDdtek")) {
345
	             Class.forName(clsSQLServerDdtek);
346
	             mUrl = urlDataDirectSQLServer + mServer;
347
	         }
348
	        else {
349
	            Class.forName(clsSQLServer2005);
350
	            mUrl = urlDefault; 
351
	        }
352
	        logger.debug("Connection String: " + mUrl);	
353
	        return true;
354
	    }catch (ClassNotFoundException e){
355
	        logger.error("Datenbank-Treiber-Klasse konnte nicht geladen werden\n" + "Exception: " + e.toString());
356
	        return false;
357
	    }
358
    }
359
 
360
    
361
/* ******************** SETTER *************************************/
362

    
363
    /**
364
     * @param query
365
     */
366
    public Source setQuery (String query){
367
        mQuery = query;
368
        return this;
369
    }
370
    
371
    /**
372
     * Sets the username.
373
     * @param userName
374
     */
375
    public Source setUsername (String userName){
376
    	if (userName == null){
377
    		this.mUserName = userNameDefault;
378
    	}else{
379
    		this.mUserName = userName;
380
    	}
381
    	this.connExist = false;
382
		return this;
383
    }
384
        
385
    /**
386
     * Sets the password.
387
     * @param pwd
388
     */
389
    public Source setPassword (String pwd){
390
    	if (pwd == null){
391
    		this.mPwd = pwdDefault;
392
    	}else{
393
    		this.mPwd = pwd;
394
    	}
395
    	this.connExist = false;
396
		return this;
397
	}
398
    
399
    /**
400
     * Sets the username and password.
401
     * @param userName
402
     * @param pwd
403
     */
404
    public Source setUserAndPwd (String userName, String pwd){
405
    	setUsername(userName);
406
    	setPassword(pwd);
407
    	return this;
408
	}
409
    
410
    /**
411
     * Sets the port.
412
     * @param userName
413
     * @param pwd
414
     */
415
    public Source setPort (int port){
416
    	this.mPort = port;
417
		this.connExist = false;
418
		return this;
419
	}
420
    
421
    public String getDatabase(){
422
    	return mDb;
423
    }
424
    
425
    public String getServer(){
426
    	return mServer;
427
    }
428
    
429
    
430
    public boolean isDoLog() {
431
		return doLog;
432
	}
433

    
434
	public void setDoLog(boolean doLog) {
435
		this.doLog = doLog;
436
	}
437
    
438
    /**
439
     * Checks if an attribute exists in the database schema. At the moment only supported
440
     * for SQL Server.
441
     * TODO implement for others.
442
     * @param tableName
443
     * @param dbAttribute
444
     * @return
445
     * @throws MethodNotSupportedException
446
     */
447
    public boolean checkColumnExists(String tableName, String dbAttribute) throws MethodNotSupportedException{
448
    	if (mDbms.equalsIgnoreCase(SQL_SERVER_2005)|| mDbms.equalsIgnoreCase(SQL_SERVER_2008) ){
449
    		String strQuery = "SELECT  Count(t.id) as n " +
450
				" FROM sysobjects AS t " +
451
				" INNER JOIN syscolumns AS c ON t.id = c.id " +
452
				" WHERE (t.xtype = 'U') AND " + 
453
				" (t.name = '" + tableName + "') AND " + 
454
				" (c.name = '" + dbAttribute + "')";
455
			ResultSet rs = getResultSet(strQuery) ;		
456
			int n;
457
			try {
458
				rs.next();
459
				n = rs.getInt("n");
460
				return n>0;
461
			} catch (SQLException e) {
462
				e.printStackTrace();
463
				return false;
464
			}
465
    	}else{
466
    		throw new MethodNotSupportedException("Check column exist is not supported by the database system");
467
    	}
468
    }
469

    
470
    @Override
471
    public String toString(){
472
    	if (mDb != null){
473
    		return mDb;
474
    	}else if (mUrl == null){
475
    		return super.toString();
476
    	}else{
477
        	return mUrl;
478
    	}
479
    }
480
    
481

    
482
}
(42-42/48)