Project

General

Profile

Download (16.5 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.io.PrintWriter;
20
import java.sql.Connection;
21
import java.sql.DriverManager;
22
import java.sql.ResultSet;
23
import java.sql.SQLException;
24
import java.sql.Statement;
25

    
26
import org.apache.http.MethodNotSupportedException;
27
import org.apache.log4j.Logger;
28

    
29
import eu.etaxonomy.cdm.common.AccountStore;
30
import eu.etaxonomy.cdm.database.ICdmDataSource;
31
import eu.etaxonomy.cdm.database.update.DatabaseTypeNotSupportedException;
32

    
33

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

    
44
/* ************ Constants **************************************/
45
    //Mode
46
	private final static boolean DEBUG_MODE = false;
47
    private final static boolean DEBUG_LOG_WRITER = false;
48

    
49
    //DB info
50
//	public final static String SQL_SERVER_2000 = "SQLServer2000";
51
	public final static String SQL_SERVER_2005 = "SQLServer2005";
52
	public final static String SQL_SERVER_2008 = "SQLServer2008";
53
	public final static String ACCESS = "Access";
54
	public final static String EXCEL = "Excel";
55
	public final static String ODDBC = "ODBC";
56
	public final static String ORACLE = "Oracle";
57
	public final static String DB2 = "DB2";
58
	public final static String POSTGRESQL9 = "PostgreSQL9";
59
	public final static String MYSQL = "MySQL";
60

    
61

    
62
	//coursor mode
63
	public final static String SELECT_DIRECT = "direct";
64
	public final static String SELECT_CURSOR = "cursor";
65

    
66
    //driver class
67
//    private static String clsSQLServer2000 = "com.microsoft.jdbc.sqlserver.SQLServerDriver";
68
    private static String clsSQLServer2005 = "com.microsoft.sqlserver.jdbc.SQLServerDriver";
69
    private static String clsSQLServer2008 = "com.microsoft.sqlserver.jdbc.SQLServerDriver";
70
    private static String clsODBC = "sun.jdbc.odbc.JdbcOdbcDriver";
71
    private static String clsOracle = "oracle.jdbc.driver.OracleDriver";
72
    private static String clsDB2 = "COM.ibm.db2.jdbc.net.DB2Driver";
73
    private static String clsSQLServerDdtek = "com.ddtek.jdbc.sqlserver.SQLServerDriver";
74
    private static String clsDefault = "com.microsoft.jdbc.sqlserver.SQLServerDriver";
75
    private static String clsPostgreSQL = "org.postgresql.Driver";
76
    private static String clsMySQL = "com.mysql.jdbc.Driver";
77

    
78
    //url
79
//    private static String urlSQLServer = "jdbc:microsoft:sqlserver://";
80
    private static String urlSQLServer2005 = "jdbc:sqlserver://";
81
    private static String urlSQLServer2008 = "jdbc:sqlserver://";
82
    private static String urlDB2 = "jdbc:db2://";
83
    private static String urlOracle = "jdbc:oracle:thin:@:1243:";
84
    private static String urlDataDirectSQLServer = "jdbc:datadirect:sqlserver://";
85
    private static String urlODBC = "jdbc:odbc:";
86
    private static String urlPostgreSQL = "jdbc:postgresql://";
87
    private static String urlMySQL = "jdbc:mysql://";
88

    
89

    
90
/* *************** VARIABLES *******************************/
91
    private Connection mConn;
92
    private Statement mStmt;
93
    private String mQuery;
94
    private String mUrl = null;
95
    private String mDb = null;
96
    private int mPort = 1433; //default port TODO 2 currently only for SQLServer, needs to be implemented also for othe DBMS
97
    private String mDbms = null;
98
    private String mServer = null;
99
    private boolean isCursor;
100
    private boolean connExist = false; //does a Connection exist?
101
    private String mUserName;
102
    private String mPwd;
103

    
104
	private boolean doLog = false;
105

    
106

    
107
	private static String userNameDefault = "sa"; //default user
108
    private static String pwdDefault = "sa"; //default PWD
109

    
110

    
111
/* ******************** CONSTRUCTORS **********************************/
112

    
113

    
114
    /**
115
     * Creates a source and sets the according variables
116
     * @param dbms name of database management system (e.g. "SQLServer", "Access", "Excel", "Oracle"
117
	 * @param server name of server, if dbms is ODBC, this must be the ODBC name
118
	 * @param db name of database
119
	*/
120
    public Source(String dbms, String server, String db){
121
    	mDbms = dbms;
122
        mServer = server;
123
        mDb = db;
124
        this.mPwd = pwdDefault;
125
        this.mUserName = userNameDefault;
126
    }
127

    
128
    /**
129
     * Creates a source and sets the query string
130
     * @param dbms name of database management system (e.g. "SQLServer", "Access", "Excel", "Oracle"
131
	 * @param server name of server, if dbms is ODBC, this must be the ODBC name
132
	 * @param db name of database
133
     * @param query the query
134
     */
135
    public Source(String dbms, String server, String db, String query){
136
        this(dbms, server, db);
137
        this.setQuery(query);
138
    }
139

    
140
    /**
141
    * Creates a source and sets the parameter.
142
     * @param cursor access mode, if true 'cursor', if false 'direct'
143
    */
144
    public Source(String dbms, String server, String db, boolean cursor)   {
145
        this(dbms, server, db);
146
    	isCursor = cursor;
147
    }
148

    
149

    
150
    /**
151
    * Creates a source and sets the parameter. If port is -1 the databases default port is used.
152
    * @param dbms name of database management system (e.g. "SQLServer", "Access", "Excel", "Oracle"
153
    * @param server name of server, if dbms is ODBC, this must be the ODBC name
154
    * @param db name of database
155
    * @param port the databases port (-1: use default port)
156
    */
157
    public Source(String dbms, String server, String db, int port) {
158
        this(dbms, server, db);
159
        if (port != -1){
160
        	this.setPort(port);
161
        };
162
    }
163

    
164
    /**
165
     * Creates a source with parameters of a ICdmDataSource instance
166
     *
167
     * @param cdmDataSource
168
     */
169
    public Source(ICdmDataSource cdmDataSource){
170
    	mDbms = cdmDataSource.getDatabaseType().getName();
171
        mServer = cdmDataSource.getServer();
172
        mDb = cdmDataSource.getDatabase();
173
        mPwd = cdmDataSource.getPassword();
174
        mUserName = cdmDataSource.getUsername();
175
        this.setPort(cdmDataSource.getPort());
176
    }
177

    
178
//********************* METHODS *****************************************************/
179

    
180
    //******* RESULTSETS *******************//
181
    /**
182
     * Returns the Resultset for query 'query'.
183
     * Does not change the Sources query-string!!
184
     * @return Resultset for the query.
185
     */
186
    public ResultSet getResultSet (String query){
187
    	ResultSet rs;
188
    	try {
189
            this.getConnection(); //establish connection
190
        	if (query == null){
191
        		return null;
192
        	}
193
            mStmt = mConn.createStatement();
194
            rs = mStmt.executeQuery(query);
195
            return rs;
196
        }catch(Exception e){
197
            logger.error("Problems when creating Resultset for query \n  " + query + " \n" + "Exception: " + e);
198
            throw new RuntimeException(e);
199
        }
200
    }
201

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

    
225

    
226
    /**
227
     * Returns the Resultset for Sources query.
228
     * @return Resultset for the Sources query
229
     */
230
    public ResultSet getResultSet (){
231
    	return getResultSet(mQuery);
232
    }
233

    
234

    
235
    // ***************CONNECTION *************************************//
236
    /**
237
     * Returns the connection.
238
     * @return the Sources connection
239
     */
240
    public Connection getConnection(){
241
    	try {
242
			if (this.connExist == false){
243
				if (mConn != null){
244
					mConn.close();
245
				}
246
				this.makeConnection() ;
247
    		}
248
			return this.mConn;
249
		} catch (SourceConnectionException e) {
250
			throw new RuntimeException("Error when establishing Connection.", e);
251
		} catch (SQLException e) {
252
			throw new RuntimeException("SQLException in getConnection.", e);
253
		}
254
    }
255

    
256

    
257
    /**
258
     * Makes the connection.
259
     * @return true if connection created
260
     * @throws SourceConnectionException
261
     */
262
    private boolean makeConnection()throws SourceConnectionException {
263
    	if (doLog ){
264
    		DriverManager.setLogWriter(new PrintWriter(System.out));
265
    	}
266
    	try {
267
			if (makeConnectionString() == false){
268
				throw new SourceConnectionException ("Error in Connection String");
269
			}
270
			if (mDbms.equalsIgnoreCase(ODDBC) ){
271
				//not necessarily limited to ODBC
272
				java.util.Properties prop = new java.util.Properties();
273
//			    prop.put("charSet", "Big5");
274
			    prop.put("user", mUserName);
275
			    prop.put("password", mPwd);
276
//			    DriverManager.setLogWriter(new PrintWriter(System.out));
277
			    mConn = DriverManager.getConnection(mUrl, prop);
278
			}else{
279
				mConn = DriverManager.getConnection(mUrl, mUserName, mPwd);
280
			}
281

    
282

    
283

    
284
			mConn.setCatalog(mDb);  //
285
			logger.info("Connected to " + mConn.getCatalog());
286
			mStmt = mConn.createStatement();
287
			this.connExist = true;
288
			return true;
289
		}catch (SQLException e){
290
            logger.error("Problems when trying to open the database !!!\n" +
291
                    "URL: " + mUrl  + "\n" +
292
                    "Exception: " + e);
293
            throw new SourceConnectionException ();
294
        }
295
    }
296

    
297
    /**
298
     * Makes the connection string
299
     * @return false if ClassNotFoundException, else true
300
     */
301
    private boolean makeConnectionString(){
302
    	String selectMethod;
303
        String server;
304

    
305
    	if (isCursor) {
306
            selectMethod = SELECT_CURSOR;
307
        } else {
308
            selectMethod = SELECT_DIRECT;
309
        }
310
	    try{
311
	        if (DEBUG_LOG_WRITER) {
312
                DriverManager.setLogWriter((new PrintWriter(System.out)));
313
            } else if (mDbms.equalsIgnoreCase(SQL_SERVER_2005)) {
314
	            Class.forName(clsSQLServer2005);
315
	            server = mServer + ":" + mPort;
316
	            mUrl = urlSQLServer2005 + server + ";databaseName=" + mDb +";SelectMethod="+ selectMethod;
317
	        }
318
	        else if (mDbms.equalsIgnoreCase(SQL_SERVER_2008)) {
319
	            Class.forName(clsSQLServer2008);
320
	            server = mServer + ":" + mPort;
321
	            mUrl = urlSQLServer2008 + server + ";databaseName=" + mDb +";SelectMethod="+ selectMethod;
322
	        }
323
	        else if (mDbms.equalsIgnoreCase(ACCESS)) {
324
	        	Class.forName(clsODBC);
325

    
326
	        	//mDb must be the file path
327
	        	mUrl = urlODBC + "Driver={Microsoft Access Driver (*.mdb)};DBQ=";
328
	        	mUrl += mDb.trim() + ";DriverID=22;READONLY=false}";
329
	        }
330
	        else if (mDbms.equalsIgnoreCase(EXCEL)) {
331
	            Class.forName(clsODBC);
332
	            mUrl = urlODBC + "jdbc:odbc:Driver={Microsoft Excel Driver (*.xls)};DBQ=";
333
	            mUrl += mDb.trim() + ";DriverID=22;READONLY=false";
334
	        }
335
	        else if (mDbms.equalsIgnoreCase(ODDBC)) {
336
	            //mDb must be the System DNS name
337
	        	Class.forName(clsODBC);
338
	            mUrl = urlODBC + mDb ;
339
	        }
340
	        else if (mDbms.equalsIgnoreCase(ORACLE)) {
341
	            Class.forName(clsOracle);
342
	            mUrl = urlOracle + mDb ;
343
	        }
344
	        else if (mDbms.equalsIgnoreCase(DB2)) {
345
	            Class.forName(clsDB2);
346
	            mUrl = urlDB2 + mDb;
347
	        }
348
	        else if (mDbms.equalsIgnoreCase("SQLServerDdtek")) {
349
	             Class.forName(clsSQLServerDdtek);
350
	             mUrl = urlDataDirectSQLServer + mServer;
351
	        }
352
	        else if (mDbms.equalsIgnoreCase(POSTGRESQL9)) {
353
	            Class.forName(clsPostgreSQL);
354
	            server = mServer + ":" + mPort;
355
	            mUrl = urlPostgreSQL + server+ "/" + mDb;
356
	        }
357
	        else if (mDbms.equalsIgnoreCase(MYSQL)) {
358
                Class.forName(clsMySQL);
359
                server = mServer + ":" + mPort;
360
                mUrl = urlMySQL + server+ "/" + mDb + "?useUnicode=true&characterEncoding=utf8" + "&zeroDateTimeBehavior=convertToNull";
361
            }
362
	        else {
363
	            throw new RuntimeException("Unsupported Database type");
364
	        }
365
	        logger.debug("Connection String: " + mUrl);
366
	        return true;
367
	    }catch (ClassNotFoundException e){
368
	        logger.error("Datenbank-Treiber-Klasse konnte nicht geladen werden\n" + "Exception: " + e.toString());
369
	        return false;
370
	    }
371
    }
372

    
373

    
374
/* ******************** SETTER *************************************/
375

    
376
    /**
377
     * @param query
378
     */
379
    public Source setQuery (String query){
380
        mQuery = query;
381
        return this;
382
    }
383

    
384
    /**
385
     * Sets the username.
386
     * @param userName
387
     */
388
    public Source setUsername (String userName){
389
    	if (userName == null){
390
    		this.mUserName = userNameDefault;
391
    	}else{
392
    		this.mUserName = userName;
393
    	}
394
    	this.connExist = false;
395
		return this;
396
    }
397

    
398
    /**
399
     * Sets the password.
400
     * @param pwd
401
     */
402
    public Source setPassword (String pwd){
403
    	if (pwd == null){
404
    		this.mPwd = pwdDefault;
405
    	}else{
406
    		this.mPwd = pwd;
407
    	}
408
    	this.connExist = false;
409
		return this;
410
	}
411

    
412
    /**
413
     * Sets the username and password.
414
     * @param userName
415
     * @param pwd
416
     */
417
    public Source setUserAndPwd (String userName, String pwd){
418
    	setUsername(userName);
419
    	setPassword(pwd);
420
    	return this;
421
	}
422

    
423
    /**
424
     * Sets the port.
425
     * @param userName
426
     * @param pwd
427
     */
428
    public Source setPort (int port){
429
    	this.mPort = port;
430
		this.connExist = false;
431
		return this;
432
	}
433

    
434
    public String getDatabase(){
435
    	return mDb;
436
    }
437

    
438
    public String getServer(){
439
    	return mServer;
440
    }
441

    
442

    
443
    public boolean isDoLog() {
444
		return doLog;
445
	}
446

    
447
	public void setDoLog(boolean doLog) {
448
		this.doLog = doLog;
449
	}
450

    
451
    /**
452
     * Checks if an attribute exists in the database schema. At the moment only supported
453
     * for SQL Server.
454
     * TODO implement for others.
455
     * @param tableName
456
     * @param dbAttribute
457
     * @return
458
     * @throws MethodNotSupportedException
459
     */
460
    public boolean checkColumnExists(String tableName, String dbAttribute) throws DatabaseTypeNotSupportedException{
461
    	if (mDbms.equalsIgnoreCase(SQL_SERVER_2005)|| mDbms.equalsIgnoreCase(SQL_SERVER_2008) ){
462
    		String strQuery = "SELECT  Count(t.id) as n " +
463
				" FROM sysobjects AS t " +
464
				" INNER JOIN syscolumns AS c ON t.id = c.id " +
465
				" WHERE (t.xtype = 'U') AND " +
466
				" (t.name = '" + tableName + "') AND " +
467
				" (c.name = '" + dbAttribute + "')";
468
			ResultSet rs = getResultSet(strQuery) ;
469
			int n;
470
			try {
471
				rs.next();
472
				n = rs.getInt("n");
473
				return n>0;
474
			} catch (SQLException e) {
475
				e.printStackTrace();
476
				return false;
477
			}
478
    	}else{
479
    		throw new DatabaseTypeNotSupportedException("Check column exist is not supported by the database system");
480
    	}
481
    }
482

    
483
    @Override
484
    public String toString(){
485
    	if (mDb != null){
486
    		return mDb;
487
    	}else if (mUrl == null){
488
    		return super.toString();
489
    	}else{
490
        	return mUrl;
491
    	}
492
    }
493

    
494
    public static void main(String[] arg){
495
        Source source = EDAPHOBASE8();
496
        ResultSet a = source.getResultSet("SELECT count(*) FROM tax_taxon");
497
        try {
498
            a.next();
499
            long size = a.getLong(1);
500
        } catch (SQLException e) {
501
            // TODO Auto-generated catch block
502
            e.printStackTrace();
503
        }
504
        System.exit(0);
505
    }
506

    
507
    private static Source EDAPHOBASE8(){
508
        String dbms = Source.POSTGRESQL9;  //TODO 10
509
        String strServer = "130.133.70.26";  //BGBM-PESISQL
510
        String strDB = "cdm_edapho";
511
        int port = 5432; // 5433;
512
        String userName = "postgres";
513
        return  makeSource(dbms, strServer, strDB, port, userName, null);
514
    }
515

    
516
    private static Source makeSource(String dbms, String strServer, String strDB, int port, String userName, String pwd ){
517
        //establish connection
518
        Source source = null;
519
        source = new Source(dbms, strServer, strDB);
520
        source.setPort(port);
521

    
522
        pwd = AccountStore.readOrStorePassword(dbms, strServer, userName, pwd);
523
        source.setUserAndPwd(userName, pwd);
524
        // write pwd to account store
525
        return source;
526
    }
527

    
528

    
529
}
(54-54/63)