ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/owl/trunk/tools/ClusterConnection.java
Revision: 38
Committed: Mon Mar 20 11:37:12 2006 UTC (18 years, 7 months ago) by duarte
File size: 15569 byte(s)
Log Message:
Added getAllIdxAndClients method:
gets all ids and client_names for a certain key
Line User Rev File contents
1 duarte 16 package tools;
2 duarte 15 import java.sql.*;
3    
4     /**
5     * ClusterConnection class to wrap the master/node mysql servers so that is transparent to other programs
6     * @author Jose Duarte
7     */
8    
9     public class ClusterConnection {
10    
11 duarte 34 private final String URL= "jdbc:mysql://";
12     private String MASTERDB="key_master";
13     private final String MASTERHOST="white";
14 duarte 15 private Connection nCon;
15     private Connection mCon;
16     public String keyTable;
17     public String key;
18     public String idxColumn;
19     public String host;
20     public String db;
21     private String user;
22     private String password;
23 duarte 34
24     /**
25     * Create a ClusterConnection passing a key.
26 duarte 35 * @param db the database name
27     * @param key the key name: if asu_id is the ids from which my key is based on, then the key name is "asu"
28     * @param user the user name for connection to both master and nodes
29     * @param password the password for connection to both master and nodes
30 duarte 34 */
31 duarte 15 public ClusterConnection (String db,String key, String user,String password) {
32 duarte 17 new ClusterConnection(db,user,password);
33     this.key=key; //can't use the setKey method here before we've got the db field initialized
34 duarte 15 setIdxColumn();
35 duarte 34 setKeyTable(db);
36 duarte 15 }
37    
38 duarte 34 /**
39     * Create a ClusterConnection without passing a key. The key will be set later when we call createStatement(key,idx)
40 duarte 35 * @param db the database name
41     * @param user the user name for connection to both master and nodes
42     * @param password the password for connection to both master and nodes
43 duarte 34 */
44 duarte 15 public ClusterConnection (String db, String user,String password) {
45 duarte 17 loadMySQLDriver();
46 duarte 15 setDb(db);
47     setUser(user);
48     setPassword(password);
49     try {
50     // For nCon we create a connection to the master too.
51     // This is just a place holder because the actual node connection is not created until we create the statement
52     // If we don't do this then when closing the two connections an exception might occurr because we try to close a non existing object
53 duarte 34 this.nCon = DriverManager.getConnection(URL+MASTERHOST+"/"+MASTERDB,user,password);
54     this.mCon = DriverManager.getConnection(URL+MASTERHOST+"/"+MASTERDB,user,password);
55 duarte 15 }
56     catch(SQLException e){
57 duarte 33 System.err.println("SQLException: " + e.getMessage());
58     System.err.println("SQLState: " + e.getSQLState());
59     System.err.println("VendorError: " + e.getErrorCode());
60 duarte 34 System.err.println("Couldn't get connection to master host "+MASTERHOST+", db="+MASTERDB+", exiting.");
61 duarte 15 System.exit(2);
62     }
63     }
64    
65     public void loadMySQLDriver() {
66     try {
67     Class.forName("com.mysql.jdbc.Driver");
68     }
69     catch(Exception e) {
70 duarte 33 System.err.println(e.getMessage());
71     System.err.println("An exception occurred while loading the mysql jdbc driver, exiting.");
72 duarte 15 System.exit(1);
73     }
74     }
75     public void close() {
76     try {
77     this.nCon.close();
78     this.mCon.close();
79     }
80     catch(SQLException e) {
81 duarte 34 System.err.println("Couldn't close database connections for master: "+MASTERHOST+" and node: "+this.host+", exiting.");
82 duarte 33 System.err.println("SQLException: " + e.getMessage());
83     System.err.println("SQLState: " + e.getSQLState());
84 duarte 15 System.exit(3);
85     }
86     }
87    
88     public String getHost4Idx (int idx) {
89     String host="";
90     Statement S;
91     ResultSet R;
92     try {
93     S=mCon.createStatement();
94     String query="SELECT client_name FROM "+keyTable+" AS m INNER JOIN clients_names AS c "+
95     "ON (m.client_id=c.client_id) WHERE "+idxColumn+"="+idx+";";
96     R=S.executeQuery(query);
97     if (R.next()){
98     host=R.getString(1);
99     }
100     S.close();
101     R.close();
102     }
103     catch(SQLException e) {
104 duarte 33 System.err.println("Couldn't get the host name for idx "+idx+", exiting");
105     System.err.println("SQLException: " + e.getMessage());
106     System.err.println("SQLState: " + e.getSQLState());
107 duarte 15 System.exit(3);
108     }
109     return host;
110     }
111    
112     public void setHostFromIdx(int idx){
113     setHost(getHost4Idx(idx));
114     }
115    
116     public void setHost(String host) {
117     this.host=host;
118     try {
119 duarte 23 //Closing previous connection is essential
120     //If we don't close it a lot of connections stay open after using a ClusterConnection object for a while
121     this.nCon.close();
122 duarte 34 this.nCon=DriverManager.getConnection(URL+host+"/"+db,user,password);
123 duarte 15 }
124     catch (SQLException e){
125 duarte 33 System.err.println("SQLException: " + e.getMessage());
126     System.err.println("SQLState: " + e.getSQLState());
127 duarte 37 System.err.println("Couldn't get connection to node "+host+", database "+db+", exiting.");
128 duarte 15 System.exit(2);
129     }
130     }
131 duarte 35
132 duarte 34 /**
133     * This method is strictly private. We shouldn't call this from another class as a key might not be set when we call it
134     * and thus we can't get the client_id from the master key table. Only to be called from createStatement(key,idx)
135 duarte 35 * @param idx the value of the id for a certain key already set
136     * @return a Stament object with a connection to the node that contains idx for key
137 duarte 34 */
138     private Statement createStatement(int idx) { // to use when the field "key" is already set
139     setKeyTable();
140 duarte 15 setIdxColumn();
141     Statement S=null;
142     this.setHostFromIdx(idx);
143     try {
144     S=this.nCon.createStatement();
145     }
146     catch (SQLException e){
147 duarte 33 System.err.println("SQLException: " + e.getMessage());
148     System.err.println("SQLState: " + e.getSQLState());
149     System.err.println("Couldn't create statement for the node connection, idx= "+idx+", exiting.");
150 duarte 15 System.exit(2);
151     }
152     return S;
153     }
154 duarte 35
155 duarte 34 /**
156 duarte 35 * This method is used to create a statement passing the key and idx. It will create a connection the the right node
157     * and return a Statement for that connection
158     * @param idx the key name
159     * @param idx the id value for that key
160     * @return a Statement object with a connection to the node that contains idx for key
161 duarte 34 */
162 duarte 15 public Statement createStatement(String key,int idx) {
163     setKey(key);
164     return createStatement(idx);
165     }
166    
167 duarte 35 /**
168     * To set keyTable field in constructor (i.e. first time)
169     * @param db the database name
170     */
171     public void setKeyTable(String db) {
172 duarte 15 this.keyTable=db+"_"+this.key+"_list_master";
173     }
174    
175 duarte 35 /**
176     * To se the keyTable field when db is already set
177     *
178     */
179     public void setKeyTable() {
180 duarte 15 this.keyTable=this.db+"_"+this.key+"_list_master";
181     }
182    
183 duarte 34 public String getKeyTable() {
184 duarte 15 return this.keyTable;
185     }
186    
187     public void setIdxColumn() {
188     this.idxColumn=this.key+"_id";
189     }
190    
191     public void setUser(String user) {
192     this.user=user;
193     }
194    
195     public void setPassword(String password) {
196     this.password=password;
197     }
198    
199     public void setDb(String db){
200     this.db=db;
201     }
202    
203     public void setKey(String key){
204     this.key=key;
205 duarte 34 setKeyTable();
206 duarte 15 setIdxColumn();
207     }
208    
209     public Statement createMasterStatement() {
210     Statement S=null;
211     try {
212     S=this.mCon.createStatement();
213     }
214     catch (SQLException e){
215 duarte 33 System.err.println("SQLException: " + e.getMessage());
216     System.err.println("SQLState: " + e.getSQLState());
217     System.err.println("Couldn't create statement for the master connection, exiting.");
218 duarte 15 System.exit(2);
219     }
220     return S;
221     }
222    
223     public ResultSet getAllIdxFromMaster(String key) {
224     this.setKey(key);
225     String query;
226     Statement S;
227     ResultSet R=null;
228     try {
229     query="SELECT "+idxColumn+" FROM "+keyTable+";";
230     S=this.mCon.createStatement();
231     R=S.executeQuery(query);
232     //S.close(); // apparently it doesn't work if we close the Statement!! Don't know why!
233     }
234     catch (SQLException e){
235 duarte 33 System.err.println("SQLException: " + e.getMessage());
236     System.err.println("SQLState: " + e.getSQLState());
237 duarte 34 System.err.println("Couldn't get all indices from columnn "+idxColumn+" in table "+keyTable+" from "+MASTERDB+" database in "+MASTERHOST+", exiting.");
238 duarte 15 System.exit(2);
239     }
240     return R;
241     }
242 duarte 35 /**
243 duarte 38 * To get all ids and clients_names pairs for a certain key. Useful when need to submit to all hosts using qsub -q
244     * @param key the name of the key
245     * @return ResultSet with the pairs: id, client_name
246     */
247     public ResultSet getAllIdxAndClients (String key){
248     this.setKey(key);
249     String query;
250     Statement S;
251     ResultSet R = null;
252     try {
253     query="SELECT a."+idxColumn+",c.client_name FROM "+keyTable+" AS a INNER JOIN clients_names AS c ON (a.client_id=c.client_id);";
254     S=this.mCon.createStatement();
255     R=S.executeQuery(query);
256     //S.close(); // apparently it doesn't work if we close the Statement!! Don't know why!
257     }
258     catch (SQLException e){
259     System.err.println("SQLException: " + e.getMessage());
260     System.err.println("SQLState: " + e.getSQLState());
261     System.err.println("Couldn't get all indices/client_names pairs from table "+keyTable+" from "+MASTERDB+" database in "+MASTERHOST+", exiting.");
262     System.exit(2);
263     }
264     return R;
265     }
266    
267     /**
268 duarte 35 * To get client_id for a certain idx and key
269     * @param key the key name
270     * @param idx the id value for that key
271     * @return the client_id for node that has the data for the idx for that key
272     */
273 duarte 15 //TODO will need to change the query. In general this method would return more than 1 client_id if the idx is not unique
274     public int getHostId4Idx (String key,int idx) {
275     int hostId=0;
276     this.setKey(key);
277     Statement S;
278     ResultSet R;
279     String query;
280     int countCids=0;
281     try {
282     S=mCon.createStatement();
283     query="SELECT count(client_id) FROM "+keyTable+" WHERE "+idxColumn+"="+idx+";";
284     R=S.executeQuery(query);
285     if (R.next()){
286     countCids=R.getInt(1);
287     }
288     if (countCids!=1){
289 duarte 37 System.err.println("Error! the number of client_id for idx "+idxColumn+"= "+idx+" is 0 or bigger than 1." +
290     " The values where taken from host: "+MASTERHOST+", database: "+MASTERDB+", table: "+keyTable+". Check what's wrong! Exiting now.");
291 duarte 15 System.exit(2);
292     }
293     else {
294     query="SELECT client_id FROM "+keyTable+" WHERE "+idxColumn+"="+idx+";";
295     R=S.executeQuery(query);
296     if (R.next()){
297     hostId=R.getInt(1);
298     }
299     }
300     S.close();
301     R.close();
302     }
303     catch(SQLException e) {
304 duarte 33 System.err.println("Couldn't get the host id for idx "+idxColumn+"="+idx+", exiting");
305     System.err.println("SQLException: " + e.getMessage());
306     System.err.println("SQLState: " + e.getSQLState());
307 duarte 15 System.exit(3);
308     }
309     return hostId;
310     }
311    
312     public void insertIdxInMaster(String key, int clientId) {
313     Statement S;
314     String query;
315     this.setKey(key);
316     try {
317     S=this.mCon.createStatement();
318     query="INSERT INTO "+this.keyTable+" (client_id) VALUES ("+clientId+");";
319     S.executeUpdate(query);
320     S.close();
321     }
322     catch (SQLException E) {
323 duarte 33 System.err.println("SQLException: " + E.getMessage());
324     System.err.println("SQLState: " + E.getSQLState());
325 duarte 34 System.err.println("Couldn't insert new "+this.idxColumn+" in master table "+this.getKeyTable()+". The client_id for it was "+clientId+". Exiting.");
326 duarte 15 System.exit(2);
327     }
328     }
329    
330     public void insertIdxInMaster(String keySrc,String keyDest,int idxSrc) {
331     this.setKey(keySrc);
332     int clientId=0;
333     clientId=this.getHostId4Idx(keySrc,idxSrc);
334     insertIdxInMaster(keyDest,clientId);
335     }
336    
337     public int getLastInsertId(String key) {
338     int lastIdx=0;
339     this.setKey(key);
340     Statement S;
341     ResultSet R;
342     String query = "";
343     try {
344     S = this.mCon.createStatement();
345     query = "SELECT LAST_INSERT_ID() FROM "+this.keyTable+" LIMIT 1;";
346     R = S.executeQuery(query);
347     if (R.next()) {
348     lastIdx=R.getInt(1);
349     }
350     R.close();
351     S.close();
352     }
353     catch (SQLException E) {
354 duarte 33 System.err.println("Couldn't get the last insert id for key type "+this.idxColumn+" from table "+this.keyTable+". Exiting");
355     System.err.println("SQLException: " + E.getMessage());
356     System.err.println("SQLState: " + E.getSQLState());
357 duarte 15 System.exit(3);
358     } // end try/catch connection
359     return lastIdx;
360     } // end getGraphId
361 duarte 21
362     public int[][] getIdxSet(String key) {
363     int[][] indMatrix=null;
364     this.setKey(key);
365     String query;
366     Statement S;
367     ResultSet R;
368     try {
369     // STEP 1 -- getting set of all client_ids
370     S=this.mCon.createStatement();
371     query="SELECT count(distinct client_id) FROM "+keyTable+";";
372     int count=0;
373     R=S.executeQuery(query);
374     if (R.next()){
375     count=R.getInt(1);
376     }
377     query="SELECT DISTINCT client_id FROM "+keyTable+" ORDER BY client_id;";
378     //R.close();
379     //S.close();
380     R=S.executeQuery(query);
381    
382     // STEP 2 -- putting sets of indices counts into temp tables c_<client_id> with a serial auto_increment field
383     int[] clids=new int[count]; //array to store all client_ids. To be used in loops later
384     int i=0;
385     while (R.next()){
386     Statement Sloop=this.mCon.createStatement();
387     int clid=R.getInt(1);
388     query="CREATE TEMPORARY TABLE c_"+clid+" (serial int(11) NOT NULL AUTO_INCREMENT,"+idxColumn+" int(11),client_id int(11), PRIMARY KEY(serial));";
389     Sloop.executeUpdate(query);
390     query="INSERT INTO c_"+clid+" ("+idxColumn+",client_id) SELECT "+idxColumn+",client_id FROM "+keyTable+" WHERE client_id="+clid+";";
391     Sloop.executeUpdate(query);
392     clids[i]=clid;
393     i++;
394     Sloop.close();
395     }
396    
397     // STEP3 -- merging all c_<client_id> tables into a temp table tmp_allcs and selecting the client_id with the maximum count
398     //query="SELECT client_id,count(*) as c FROM c_34 GROUP BY client_id UNION SELECT client_id,count(*) as c FROM c_32 GROUP BY client_id;";
399     query="DROP TABLE IF EXISTS tmp_allcs;";
400     S.executeUpdate(query);
401     //this table must be permanent! otherwise cannot do the select max(c) later
402     query="CREATE TABLE IF NOT EXISTS tmp_allcs (client_id int(11), c int(11)) ENGINE=MEMORY;";
403     S.executeUpdate(query);
404     String unionStr="SELECT client_id,count(*) AS c FROM c_"+clids[0]+" GROUP BY client_id";
405     for (i=1;i<clids.length;i++) {
406     unionStr+=" UNION SELECT client_id,count(*) AS c FROM c_"+clids[i]+" GROUP BY client_id";
407     }
408     query="INSERT INTO tmp_allcs "+unionStr+";";
409     S.executeUpdate(query);
410     query="SELECT client_id,c FROM tmp_allcs WHERE c=(SELECT max(c) FROM tmp_allcs);";
411     R=S.executeQuery(query);
412     int clidMaxIdxCount=0;
413     int maxIdxCount=0;
414     if (R.next()) {
415     clidMaxIdxCount=R.getInt(1);
416     maxIdxCount=R.getInt(2);
417     }
418     query="DROP TABLE tmp_allcs;";
419     S.executeUpdate(query);
420    
421     // STEP 4 -- join all c_<client_id> tables into a table with a serial column, and c_<client_id> columns each of them with the indices for each client_id
422     //query="SELECT c_34.serial,c_34.asu_id AS c_34,c_32.asu_id AS c_32,c_36.asu_id AS c_36 FROM c_34 LEFT JOIN c_32 ON (c_34.serial=c_32.serial) LEFT JOIN c_36 ON (c_34.serial=c_36.serial);";
423     String selectStr="c_"+clidMaxIdxCount+".serial, c_"+clidMaxIdxCount+"."+idxColumn+" AS c_"+clidMaxIdxCount;
424     String fromStr="c_"+clidMaxIdxCount;
425     for (i=0;i<clids.length;i++) {
426     if (clids[i]!=clidMaxIdxCount){
427     selectStr+=", c_"+clids[i]+"."+idxColumn+" AS c_"+clids[i];
428     fromStr+=" LEFT JOIN c_"+clids[i]+" ON (c_"+clidMaxIdxCount+".serial=c_"+clids[i]+".serial)";
429     }
430     }
431     query="CREATE TEMPORARY TABLE indices_matrix "+"SELECT "+selectStr+" FROM "+fromStr+";";
432     S.executeUpdate(query);
433    
434     // STEP 5 -- put the table into a 2-dimensional array and return it
435     indMatrix = new int[maxIdxCount][clids.length];
436     query="SELECT * FROM indices_matrix";
437     R=S.executeQuery(query);
438     i=0;
439     while (R.next()) {
440     for (int j=0;j<clids.length;j++){
441 duarte 22 indMatrix[i][j]=R.getInt(j+2);
442 duarte 21 }
443     i++;
444     }
445     R.close();
446     S.close();
447     }
448     catch (SQLException e){
449 duarte 33 System.err.println("SQLException: " + e.getMessage());
450     System.err.println("SQLState: " + e.getSQLState());
451 duarte 34 System.err.println("Couldn't get the indices set from columnn "+idxColumn+" in table "+keyTable+" from "+MASTERDB+" database in "+MASTERHOST+", exiting.");
452 duarte 21 System.exit(2);
453     }
454     return indMatrix;
455     }
456    
457    
458 duarte 15 }

Properties

Name Value
svn:executable *