ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/owl/trunk/tools/MySQLConnection.java
Revision: 350
Committed: Thu Oct 11 12:38:07 2007 UTC (17 years, 4 months ago) by stehr
File size: 22037 byte(s)
Log Message:
Machine: added main and some other methods; MySQLConnection: added explicit handling of some exceptions
Line User Rev File contents
1 duarte 55 package tools;
2    
3     import java.io.BufferedReader;
4     import java.io.File;
5     import java.io.FileReader;
6     import java.sql.Connection;
7     import java.sql.DriverManager;
8     import java.sql.ResultSet;
9     import java.sql.SQLException;
10     import java.sql.Statement;
11     import java.util.StringTokenizer;
12     import java.io.IOException;
13 duarte 58 import java.util.ArrayList;
14 duarte 55
15     public class MySQLConnection {
16    
17     /*--------------------- constants -----------------------*/
18    
19     // -- constants for database connection --
20     static final String HOST = "white";
21     static final String USER = "";
22     static final String PASSWORD = "nieve";
23    
24     /*------------------- member variables --------------------*/
25    
26     public Connection conn;
27     private String host;
28     private String user;
29     private String password=PASSWORD;
30     private String port;
31     private String dbname;
32    
33     /*-------------------- constructors -----------------------*/
34    
35 duarte 80 /**
36 duarte 55 * Connect to database using the given server, user and password
37 duarte 80 * @param dbServer
38     * @param dbUserName
39     * @param dbPassword
40 duarte 202 * @throws SQLException
41 duarte 55 */
42 duarte 202 public MySQLConnection(String dbServer, String dbUserName, String dbPassword) throws SQLException {
43 duarte 55 loadMySQLDriver();
44     host=dbServer;
45     user=dbUserName;
46     password=dbPassword;
47     port="";
48     dbname="";
49     String connStr="jdbc:mysql://"+host+port+"/"+dbname;
50 duarte 202
51     conn = DriverManager.getConnection(connStr, user, password);
52 duarte 55 }
53    
54     /**
55 duarte 59 * Connect to database using the given server, user, password and dbname.
56     * Please always use this constructor in preference rather than constructing without specifying a database
57 duarte 80 * @param dbServer
58     * @param dbUserName
59     * @param dbPassword
60     * @param dbName
61 duarte 202 * @throws SQLException
62 duarte 55 */
63 duarte 202 public MySQLConnection(String dbServer, String dbUserName, String dbPassword, String dbName) throws SQLException {
64 duarte 62 loadMySQLDriver();
65     host=dbServer;
66     user=dbUserName;
67     password=dbPassword;
68     port="";
69     dbname=dbName;
70     String connStr="jdbc:mysql://"+host+port+"/"+dbname;
71 duarte 202
72     conn = DriverManager.getConnection(connStr, user, password);
73 duarte 55 }
74    
75     /**
76 duarte 176 * Connect to database using the given server and dbName
77     * Password taken from default, user name from unix user name
78     * @param dbServer
79     * @param dbName
80 duarte 202 * @throws SQLException
81 duarte 176 */
82 duarte 202 public MySQLConnection(String dbServer, String dbName) throws SQLException {
83 duarte 176 loadMySQLDriver();
84     host=dbServer;
85     user=getUserName();
86     port="";
87     dbname=dbName;
88     String connStr="jdbc:mysql://"+host+port+"/"+dbname;
89 duarte 202
90     conn = DriverManager.getConnection(connStr, user, password);
91 duarte 176 }
92    
93     /**
94 duarte 55 * Connect to database using the given server, user, password, dbname and port
95 duarte 59 * Only needed if mysql server uses a port different from the standard 3306
96 duarte 80 * @param dbServer
97     * @param dbUserName
98     * @param dbPassword
99     * @param dbName
100     * @param portNum
101 duarte 202 * @throws SQLException
102 duarte 55 */
103 duarte 202 public MySQLConnection(String dbServer, String dbUserName, String dbPassword, String dbName, int portNum) throws SQLException {
104 duarte 55 loadMySQLDriver();
105     host=dbServer;
106     user=dbUserName;
107     password=dbPassword;
108     port=":"+portNum;
109     dbname=dbName;
110     String connStr="jdbc:mysql://"+host+port+"/"+dbname;
111 duarte 202
112     conn = DriverManager.getConnection(connStr, user, password);
113 duarte 55 }
114    
115     /**
116 duarte 80 * Connect to database giving a connection file
117     * @param connFile the connection file's name
118 duarte 202 * @throws SQLException
119 duarte 55 */
120 duarte 202 public MySQLConnection(String connFile) throws SQLException {
121 duarte 55 loadMySQLDriver();
122     readConnectionFile(connFile);
123     String connStr="jdbc:mysql://"+host+port+"/"+dbname;
124 duarte 202
125     conn = DriverManager.getConnection(connStr, user, password);
126 duarte 55 }
127    
128    
129     /*---------------------- methods -------------------------*/
130    
131 duarte 176 /** get user name from operating system (for use as database username) */
132 duarte 177 public static String getUserName() {
133 duarte 176 String user = null;
134     user = System.getProperty("user.name");
135     if(user == null) {
136     System.err.println("Could not get user name from operating system. Exiting");
137     System.exit(1);
138     }
139     return user;
140     }
141    
142 duarte 109 public static void loadMySQLDriver() {
143 duarte 55 try {
144     Class.forName("com.mysql.jdbc.Driver").newInstance();
145     }
146 stehr 350 catch(IllegalAccessException e) {
147 duarte 55 e.printStackTrace();
148     System.err.println("An exception occurred while loading the mysql jdbc driver, exiting.");
149     System.exit(1);
150     }
151 stehr 350 catch(InstantiationException e) {
152     e.printStackTrace();
153     System.err.println("An exception occurred while loading the mysql jdbc driver, exiting.");
154     System.exit(1);
155     }
156     catch(ClassNotFoundException e) {
157     e.printStackTrace();
158     System.err.println("An exception occurred while loading the mysql jdbc driver, exiting.");
159     System.exit(1);
160     }
161     catch(Exception e) {
162     e.printStackTrace();
163     System.err.println("An exception occurred while loading the mysql jdbc driver, exiting.");
164     System.exit(1);
165     }
166 duarte 55 }
167    
168 duarte 60 /**
169     * Used in the constructor that gets a connFile as argument. To read the connection parameters from a connection file.
170     * @param connFile
171     */
172     private void readConnectionFile(String connFile) {
173     // reads the values of the connFile into the static variables;
174     String homedir = System.getProperty("user.home");
175     if (connFile.length()==0) { // no file was specified
176     connFile=homedir+"/.my.cnf"; // assume default configuration file
177     }
178     // else the location of the connection file was given
179     // Open the configuration file
180     BufferedReader fileIn = null;
181     StringTokenizer str;
182     String item, oneLine;
183     // to control if the minimum mandatory 4 parameters are given in file
184     int paramCount=0;
185     // setting default blank values for port and dbname, they are set to blank unless fields specified in file
186     port="";
187     dbname="";
188     // list the entries in the file and decompose them
189     try {
190     fileIn = new BufferedReader(new FileReader(new File(connFile))); // open BufferedReader to file connFile
191     while ((oneLine = fileIn.readLine()) != null ) {
192     // Construct a stringTokenizer for the line that we read with : delimited
193     str = new StringTokenizer(oneLine, "="); // true sets returnDelimiters flag
194     while ( str.hasMoreTokens()) {
195     item = str.nextToken();
196     if( item.equals("host")) { // mandatory parameter
197     host=str.nextToken();
198     paramCount++;
199     break;
200     } // end if host
201     if( item.equals("port")) { // optional parameter
202     port=":"+str.nextToken();
203     break;
204     } // end if port
205     if( item.equals("user")) { // mandatory parameter
206     user=str.nextToken();
207     paramCount++;
208     break;
209     } // end if password
210     if( item.equals("password")) { // mandatory parameter
211     password=str.nextToken();
212     paramCount++;
213     break;
214     } // end if password
215     if( item.equals("database")) { // mandatory parameter
216     dbname=str.nextToken();
217     paramCount++;
218     break;
219     } // end if password
220     } // next token in this line
221     } // next line in the file
222     if (paramCount<4){
223     System.err.println("Not all mandatory parameters are given in connection file "+connFile+". Can't connect to mysql server, exiting.");
224     System.exit(1);
225     }
226     }
227     catch (IOException e) {
228     System.err.println("Couldn't open file "+connFile);
229     e.printStackTrace();
230     System.exit(1);
231     }
232    
233     try { // closing the file
234     if (fileIn != null) fileIn.close();
235     } catch (IOException e) {
236     System.err.println("Couldn't close file "+connFile);
237     e.printStackTrace();
238     }
239    
240     }
241    
242 duarte 97 public String getDbname() {
243     return dbname;
244     }
245    
246     public void setDbname(String dbname) {
247     this.dbname = dbname;
248     }
249    
250     public String getHost() {
251     return host;
252     }
253    
254     public void setHost(String host) {
255     this.host = host;
256     }
257    
258     public String getPassword() {
259     return password;
260     }
261    
262     public void setPassword(String password) {
263     this.password = password;
264     }
265    
266     public String getUser() {
267     return user;
268     }
269    
270     public void setUser(String user) {
271     this.user = user;
272     }
273    
274 duarte 55 public Statement createStatement() throws SQLException {
275     return this.conn.createStatement();
276     }
277    
278 duarte 58 public void executeSql(String query) throws SQLException{
279     Statement stmt;
280     stmt = conn.createStatement();
281     stmt.execute(query);
282     stmt.close();
283 duarte 55 }
284 duarte 60
285 duarte 55 /**
286     * @param query
287     * @return the first column of the first row of the result of the given query as a string
288     * or null if no results were returned
289 stehr 121 * TODO: How to figure out whether a database error occured?
290 duarte 55 */
291     public String getStringFromDb(String query) {
292     Statement stmt;
293     ResultSet rs;
294     String result = null;
295    
296     try {
297    
298     stmt = conn.createStatement();
299     rs = stmt.executeQuery(query);
300     if(rs.next()) {
301     result = rs.getString(1);
302     }
303     rs.close();
304     stmt.close();
305    
306     } // end try
307     catch (SQLException e) {
308     System.err.println("SQLException: " + e.getMessage());
309     System.err.println("SQLState: " + e.getSQLState());
310     System.err.println("VendorError: " + e.getErrorCode());
311     e.printStackTrace();
312     } // end catch
313    
314     return result;
315     }
316    
317     /**
318     * @param query
319     * @return the first column of the first row of the result of the given query as an integer
320     * or -1 if no results were returned
321     */
322     public int getIntFromDb(String query) {
323     Statement stmt;
324     ResultSet rs;
325     int result = -1;
326    
327     try {
328    
329     stmt = conn.createStatement();
330     rs = stmt.executeQuery(query);
331     if(rs.next()) {
332     result = rs.getInt(1);
333     }
334     rs.close();
335     stmt.close();
336    
337     } // end try
338     catch (SQLException e) {
339     System.err.println("SQLException: " + e.getMessage());
340     System.err.println("SQLState: " + e.getSQLState());
341     System.err.println("VendorError: " + e.getErrorCode());
342     e.printStackTrace();
343     } // end catch
344    
345     return result;
346     }
347    
348     public void close() {
349    
350     try {
351     conn.close();
352     } catch (SQLException e) {
353     System.err.println("SQLException: " + e.getMessage());
354     System.err.println("SQLState: " + e.getSQLState());
355     System.err.println("VendorError: " + e.getErrorCode());
356     e.printStackTrace();
357     } // end try/catch connection
358     }
359 duarte 57
360     /**
361     * Get the actual Connection object within this MySQLConnection. In case that an external library need a Connection object
362     * @return
363     */
364     public Connection getConnectionObject() {
365     return this.conn;
366     }
367 duarte 55
368 duarte 57 /**
369     * To print the db size info for the given db of this MySQLConnection.
370     * @param dbName
371     */
372     public void printDbSizeInfo (String dbName) {
373     double data = 0, index = 0, table_data = 0, table_index = 0, GB = Math.pow(2, 30);
374     String Query = null, table = null;
375     Statement Stmt = null;
376     ResultSet RS = null;
377     try {
378     Query = "SHOW TABLE STATUS FROM "+dbName;
379     Stmt = this.conn.createStatement();
380     RS = Stmt.executeQuery(Query);
381     while (RS.next()) {
382     table = RS.getString("Name");
383     table_data = RS.getDouble("Data_length");
384     table_index = RS.getDouble("Index_length");
385     data += RS.getDouble("Data_length");
386     index += RS.getDouble("Index_length");
387     System.out.println("Table "+table+"##data:"+table_data+", index:"+table_index);
388     }
389     RS.close();
390     Stmt.close();
391     System.out.println("Database "+dbName+" needs "+((data+index)/GB)+ " GB (data:"+(data/GB)+", index:"+(index/GB)+").");
392     }
393     catch (SQLException e) {
394     System.err.println("SQLException: " + e.getMessage());
395     System.err.println("SQLState: " + e.getSQLState());
396     System.err.println("VendorError: " + e.getErrorCode());
397     e.printStackTrace();
398     } // end try/catch connection
399     }
400    
401     /**
402     * To get range of a column from a table in this MySQLConnection. Note that if the connection was created without pointing
403     * to a particular database then the argument table must be specified as dbname.tablename.
404     * @param table
405     * @param column
406     * @return
407     */
408     public double[] getRange(String table, String column) {
409     String query = "";
410     Statement S;
411     ResultSet R;
412     double[] range = new double[2];
413     try {
414     query = "SELECT MIN("+column+"), MAX("+column+") FROM "+table+";";
415     S = this.conn.createStatement();
416     R = S.executeQuery(query);
417     if (R.next()) {
418     range[0] = R.getDouble(1);
419     range[1] = R.getDouble(2);
420     }
421     R.close();
422     S.close();
423     } // end try
424     catch (SQLException e) {
425     System.err.println("SQLException: " + e.getMessage());
426     System.err.println("SQLState: " + e.getSQLState());
427     System.err.println("VendorError: " + e.getErrorCode());
428     e.printStackTrace();
429     } // end catch
430     return range;
431     }
432    
433     /**
434     * To get range of a column from a table in this MySQLConnection using a given WHERE condition. Note that if
435     * the connection was created without pointing to a particular database then the argument table must
436     * be specified as dbname.tablename.
437     * @param table
438     * @param column
439     * @param whereStr
440     * @return
441     */
442     public double[] getRange(String table, String column, String whereStr) {
443     String query = "";
444     Statement S;
445     ResultSet R;
446     double[] range = new double[2];
447     try {
448     query = "SELECT MIN("+column+"), MAX("+column+") FROM "+table+" WHERE ("+whereStr+");";
449     S = this.conn.createStatement();
450     R = S.executeQuery(query);
451     if (R.next()) {
452     range[0] = R.getDouble(1);
453     range[1] = R.getDouble(2);
454     }
455     R.close();
456     S.close();
457     } // end try
458     catch (SQLException e) {
459     System.err.println("SQLException: " + e.getMessage());
460     System.err.println("SQLState: " + e.getSQLState());
461     System.err.println("VendorError: " + e.getErrorCode());
462     e.printStackTrace();
463     } // end catch
464     return range;
465     }
466 duarte 55
467 duarte 58 /**
468 duarte 60 * To get all indexes names for a certain table. Note the MySQLConnection object must be created with a non-blank database.
469     * Using INFORMATION_SCHEMA db, only works from mysql 5.0
470 duarte 58 * @param table
471     * @return
472     */
473     public String[] getAllIndexes4Table(String table) {
474     ArrayList<String> indexesAL=new ArrayList<String>();
475     String query;
476     Statement S;
477     ResultSet R;
478     try {
479 duarte 63 query = "SELECT DISTINCT INDEX_NAME FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_SCHEMA='"+dbname+"' AND TABLE_NAME='"+table+"';";
480 duarte 58 S = this.conn.createStatement();
481     R = S.executeQuery(query);
482     while (R.next()) {
483     indexesAL.add(R.getString(1));
484     }
485     R.close();
486     S.close();
487     } // end try
488     catch (SQLException e) {
489     System.err.println("SQLException: " + e.getMessage());
490     System.err.println("SQLState: " + e.getSQLState());
491     System.err.println("VendorError: " + e.getErrorCode());
492     e.printStackTrace();
493     } // end catch
494     String[] indexes=new String[indexesAL.size()];
495     int i=0;
496     for (String index:indexesAL) {
497     indexes[i]=index;
498     i++;
499     }
500     return indexes;
501     }
502 duarte 60
503 duarte 61 /**
504 duarte 64 * Gets an array of Strings with all queries necessary to create all the indexes for a certain table
505     * @param table
506     * @return
507     */
508     public String[] getCreateIndex4Table(String table){
509     String[] indexes=this.getAllIndexes4Table(table);
510     String[] createIndexQueries=new String[indexes.length];
511     for (int i=0;i<indexes.length;i++){
512     String index=indexes[i];
513     try {
514     Statement S;
515     ResultSet R;
516     String query = "SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.STATISTICS " +
517     "WHERE TABLE_SCHEMA='"+dbname+"' AND TABLE_NAME='"+table+"' AND INDEX_NAME='"+index+"' " +
518     "ORDER BY SEQ_IN_INDEX;";
519     S = this.conn.createStatement();
520     R = S.executeQuery(query);
521     String createIndexStr="CREATE INDEX "+index+" ON "+table+" (";
522     while (R.next()) {
523     String colName = R.getString(1);
524     createIndexStr+=colName+",";
525     }
526     createIndexStr=createIndexStr.substring(0,createIndexStr.lastIndexOf(","));
527     createIndexStr+=");";
528     createIndexQueries[i]=createIndexStr;
529     R.close();
530     S.close();
531     } // end try
532     catch (SQLException e) {
533     System.err.println("SQLException: " + e.getMessage());
534     System.err.println("SQLState: " + e.getSQLState());
535     System.err.println("VendorError: " + e.getErrorCode());
536     e.printStackTrace();
537     } // end catch
538     }
539     return createIndexQueries;
540     }
541    
542     /**
543 duarte 93 * To get the column type for a certain column and table
544     * @param table
545     * @param column
546     * @return
547     */
548     public String getColumnType(String table,String column){
549     String query = "SELECT COLUMN_TYPE FROM INFORMATION_SCHEMA.COLUMNS " +
550     "WHERE TABLE_SCHEMA='"+this.dbname+"' AND TABLE_NAME='"+table+"' AND COLUMN_NAME='"+column+"';";
551     String colType = this.getStringFromDb(query);
552     return colType;
553     }
554    
555     /**
556     * To findout whether a key (i.e. column) is numeric-based or text-based
557     * @param table
558     * @param key
559     * @return true if is numeric-based, false if is text-based
560     */
561     public boolean isKeyNumeric(String table, String key){
562     boolean isNumeric = false;
563     String colType = getColumnType(table,key);
564     if (colType.contains("int") || colType.contains("INT")){
565     isNumeric = true;
566     }
567     else if (colType.contains("char") || colType.contains("CHAR")){
568     isNumeric = false;
569     }
570     else {
571     System.err.println("The key '"+key+"' from table '"+table+"' is neither numeric-based (int) nor text-based (char/varchar). Check what's wrong!");
572     }
573     return isNumeric;
574     }
575    
576     /**
577 duarte 83 * To get all tables for this MySQLConnection's database.
578     * @return an array of String with all table names
579     */
580     public String[] getTables4Db(){
581     String[] tables=null;
582     ArrayList<String> tablesAL=new ArrayList<String>();
583     String query="SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='"+dbname+"' ORDER BY TABLE_NAME DESC;";
584     try {
585     Statement S = this.conn.createStatement();
586     ResultSet R=S.executeQuery(query);
587     while (R.next()){
588     tablesAL.add(R.getString(1));
589     }
590     S.close();
591     R.close();
592     tables=new String[tablesAL.size()];
593     for (int i=0;i<tablesAL.size();i++) {
594     tables[i]=tablesAL.get(i);
595     }
596     }
597     catch(SQLException e){
598     System.err.println("Couldn't get table names from "+host+" for db="+dbname);
599     System.err.println("SQLException: " + e.getMessage());
600     System.err.println("SQLState: " + e.getSQLState());
601     System.err.println("VendorError: " + e.getErrorCode());
602     e.printStackTrace();
603     }
604     return tables;
605     }
606 duarte 84
607     /**
608     * To get all distinct ordered ids from a certain key and table from this MySQLConnection
609     * @param key the key name
610     * @param table the table name
611     * @return int array containing all ids
612     */
613 duarte 93 public Integer[] getAllNumIds4KeyAndTable(String key, String table){
614     Integer[] allIds=null;
615 duarte 84 try {
616     Statement S=conn.createStatement();
617     String query="SELECT DISTINCT "+key+" FROM "+table+" ORDER BY "+key+";";
618     ResultSet R=S.executeQuery(query);
619     ArrayList<Integer> idsAL=new ArrayList<Integer>();
620     while (R.next()){
621     idsAL.add(R.getInt(1));
622     }
623 duarte 93 allIds=new Integer[idsAL.size()];
624 duarte 84 for (int i=0;i<idsAL.size();i++) {
625     allIds[i]=idsAL.get(i);
626     }
627     R.close();
628     S.close();
629     }
630     catch (SQLException e){
631     e.printStackTrace();
632     }
633     return allIds;
634     }
635 duarte 83
636 duarte 93 /**
637     * To get all distinct ordered text (i.e. char/varchar column) ids from a certain key and table from this MySQLConnection
638     * @param key the key name
639     * @param table the table name
640     * @return int array containing all ids
641     */
642     public String[] getAllTxtIds4KeyAndTable(String key, String table){
643     String[] allIds=null;
644     try {
645     Statement S=conn.createStatement();
646     String query="SELECT DISTINCT "+key+" FROM "+table+" ORDER BY "+key+";";
647     ResultSet R=S.executeQuery(query);
648     ArrayList<String> idsAL=new ArrayList<String>();
649     while (R.next()){
650     idsAL.add(R.getString(1));
651     }
652     allIds=new String[idsAL.size()];
653     for (int i=0;i<idsAL.size();i++) {
654     allIds[i]=idsAL.get(i);
655     }
656     R.close();
657     S.close();
658     }
659     catch (SQLException e){
660     e.printStackTrace();
661     }
662     return allIds;
663     }
664 duarte 84
665 duarte 94 /**
666     * To get all distinct ordered ids from a certain key and table from this MySQLConnection
667     * @param key the key name
668     * @param table the table name
669     * @return int array containing all ids
670     */
671     public Object[] getAllIds4KeyAndTable(String key, String table){
672     Object[] allIds=null;
673     try {
674     Statement S=conn.createStatement();
675     String query="SELECT DISTINCT "+key+" FROM "+table+" ORDER BY "+key+";";
676     ResultSet R=S.executeQuery(query);
677     ArrayList<String> idsAL=new ArrayList<String>();
678     while (R.next()){
679     idsAL.add(R.getString(1));
680     }
681     if (isKeyNumeric(table,key)){
682     allIds=new Integer[idsAL.size()];
683     for (int i=0;i<idsAL.size();i++) {
684     allIds[i]=Integer.parseInt(idsAL.get(i));
685     }
686     } else {
687     allIds=new String[idsAL.size()];
688     for (int i=0;i<idsAL.size();i++){
689     allIds[i]=idsAL.get(i);
690     }
691     }
692     R.close();
693     S.close();
694     }
695     catch (SQLException e){
696     e.printStackTrace();
697     }
698     return allIds;
699     }
700    
701 duarte 83 /**
702 duarte 61 * To set the sql_mode of this connection.
703     * @param sqlmode either NO_UNSIGNED_SUBTRACTION or blank
704     */
705     public void setSqlMode(String sqlmode) {
706     String query="SET SESSION sql_mode='"+sqlmode+"';";
707     try {
708     this.executeSql(query);
709     }
710     catch (SQLException e){
711     System.err.println("Couldn't change the sql mode to "+sqlmode);
712     System.err.println("SQLException: " + e.getMessage());
713     System.err.println("SQLState: " + e.getSQLState());
714     System.err.println("VendorError: " + e.getErrorCode());
715     e.printStackTrace();
716     }
717     }
718    
719 duarte 55 }

Properties

Name Value
svn:executable *