/Users/lyon/j4p/src/rdbms/SqlBean.java

1    package rdbms; 
2     
3    import java.sql.*; 
4    import java.util.Vector; 
5     
6    /** 
7     * This class provides an implementation some of the methods in the 
8     * java.sql package. This init method creates the connection to the 
9     * database and retrieves additional database information. The information 
10    * is retrieved and contained in the class variables for further 
11    * accessibility. 
12    * 
13    * @author Douglas Lyon 
14    * @version 1.00 
15    */ 
16   public class SqlBean { 
17    
18       private String url = null; 
19       private String driver = null; 
20       private String userId = null; 
21       private String password = null; 
22       private Connection c = null; 
23       private Statement statement = null; 
24       private DatabaseMetaData dbmd = null; 
25       private ResultSet rs = null; 
26       private String catalogSeparator = null; 
27    
28       private ResultSet rs_tabletypes = null; 
29    
30       private boolean isReadOnly = false; 
31       private boolean usesLocalFiles = false; 
32       private String driverName = null; 
33       private String catalogName = null; 
34       private String productName = null; 
35    
36       private String tablename = null; 
37       private String currentquery = null; 
38    
39       private String tableNames[] = null; 
40       private String nonMSysTables[] = null; 
41    
42       /** 
43        * Gets whether or not this database stores tables in a local file. * 
44        * The value is set using the DatabaseMetaData.usesLocalFiles() method 
45        * * contained in the java.sql package. This method is called and this 
46        * value is * set in this classes init() method. 
47        * 
48        * @return true if it does, false if not 
49        */ 
50       public boolean getUsesLocalFiles() { 
51           return usesLocalFiles; 
52       } 
53    
54       /** 
55        * Gets whether or not this connection to this database is read only. 
56        * The value is set using the Connection.isReadOnly() method 
57        * contained in the java.sql package. This method is called and this 
58        * value is * set in this classes init() method. 
59        * 
60        * @return true if it is, false if not 
61        */ 
62       public boolean getReadOnly() { 
63           return isReadOnly; 
64       } 
65    
66       /** 
67        * Gets this Connection's current catalog name. * The value is set 
68        * using the Connection.getCatalog() method * contained in the java.sql 
69        * package. This method is called and this value is * set in this 
70        * classes init() method. 
71        * 
72        * @return the current catalog name or null 
73        */ 
74       public String getCatalogName() { 
75           return catalogName; 
76       } 
77    
78       /** 
79        * Gets the name of this JDBC driver. 
80        * <p/> 
81        * The value is set using the DatabaseMetaData.getDriverName() method * 
82        * contained in the java.sql package. This method is called and this 
83        * value is * set in this classes init() method. 
84        * 
85        * @return the JDBC Driver name 
86        */ 
87       public String getDriverName() { 
88           return driverName; 
89       } 
90    
91       /** 
92        * Gets the name of this database product. * The value is set using the 
93        * DatabaseMetaData.getDatabaseProductName() method * contained in the 
94        * java.sql package. This method is called and this value is * set in 
95        * this classes init() method. 
96        * 
97        * @return the database product name 
98        */ 
99       public String getProductName() { 
100          return productName; 
101      } 
102   
103      /** 
104       * Gets the ResultSet contained in this instance variable rs. * 
105       * 
106       * @return this classes ResultSet 
107       */ 
108      public ResultSet getResultSet() { 
109          return rs; 
110      } 
111   
112   
113      /** 
114       * Gets the value of this current table name. * The value is set using 
115       * the SqlBean.setTableName() method * 
116       * 
117       * @return the current table name 
118       */ 
119      public String getTableName() { 
120          return tablename; 
121      } 
122   
123      /** 
124       * Gets the value of this current SQL. 
125       * <p/> 
126       * The value is set using the SqlBean.query() method 
127       * 
128       * @return the current SQL query 
129       */ 
130      public String getCurrentQuery() { 
131          return currentquery; 
132      } 
133   
134   
135      /** 
136       * Gets the table names contained in this current database. 
137       *  The table 
138       * names are placed in a ResultSet using the DatabaseMetaData.getTables() 
139       * method. 
140       *  From the ResultSet, the tables are added to a vector and 
141       * then 
142       *  converted into a String array. This method can be used at 
143       * anytime after the init() 
144       *  method is called to set the 
145       * DataBaseMetaData. 
146       * 
147       * @return the table names 
148       */ 
149      public String[] getTableNames() { 
150          Vector tableVector = new Vector(); 
151          try { 
152              rs = dbmd.getTables(null, null, null, null); 
153              rs.getMetaData(); 
154              while (rs.next()) 
155                  tableVector.addElement(rs.getString("TABLE_NAME")); 
156          } catch (SQLException e) { 
157              print(e); 
158          } 
159          int n = tableVector.size(); 
160          tableNames = new String[n]; 
161          for (int i = 0; i < n; i++) 
162              tableNames[i] = (String) tableVector.elementAt(i); 
163          return tableNames; 
164      } 
165   
166   
167      /** 
168       * Gets the names of all the Non-System Tables in this Database. * 
169       * Retrieves all the tables using the getTableNames() method. Then uses 
170       * the * getNumberOfMSysTables() to determine the number of 
171       * SystemTables contained in the * database and places those names in a 
172       * String array. This method can be used at anytime * after the init() 
173       * method is called to set the DataBaseMetaData. * 
174       * 
175       * @return the names of the non-system tables 
176       */ 
177      public String[] getNonMSysTables() { 
178   
179          String tn[] = getTableNames(); 
180          int n = tableNames.length - getNumberOfMSysTables(); 
181          nonMSysTables = new String[n]; 
182          for (int i = 0; i < n; i++) { 
183              nonMSysTables[i] = tn[i + getNumberOfMSysTables()]; 
184          } 
185   
186          return nonMSysTables; 
187      } 
188   
189   
190      /** 
191       * Gets the number of the System Tables in this Database. * Used to 
192       * help determine the table names in the getNonMSysTables() method. * 
193       * Determine the number of SystemTables contained in the database my 
194       * searching for * names starting with MSys. 
195       * 
196       * @return the number of system tables 
197       */ 
198      private int getNumberOfMSysTables() { 
199   
200          int k = 0; 
201          for (int i = 0; i < tableNames.length; i++) 
202              if (tableNames[i].startsWith("MSys")) k++; 
203          return k; 
204      } 
205   
206      /** 
207       * Gets the table types available in this database connection. The 
208       * results are ordered by table type. * The results are ordered by 
209       * table type. Typical types are: * <br>"TABLE", "VIEW", "SYSTEM 
210       * TABLE", "GLOBAL", "TEMPORARY", "LOCAL TEMPORARY", "ALIAS", 
211       * "SYNONYM". * 
212       * 
213       * @return the current SQL query 
214       */ 
215   
216      public ResultSet getTableTypes() { 
217          return rs_tabletypes; 
218      } 
219   
220   
221      /** 
222       * Sets this classes resultset instance variable, rs, based on a 
223       * provided SQL query. * 
224       * 
225       * @param myquery the SQL query 
226       */ 
227      public void setResultSet(String myquery) { 
228          rs = query(myquery); 
229      } 
230   
231   
232      /** 
233       * Sets this classes instance variable, userId, for this database 
234       * connection. * This is the database user on whose behalf the 
235       * Connection is being made for * 
236       * 
237       * @param _userId the database UserId 
238       */ 
239      public void setUserId(String _userId) { 
240          userId = _userId; 
241      } 
242   
243      /** 
244       * Sets this classes instance variable, password, for this database 
245       * connection. * The password associated with the database user on 
246       * whose behalf the *   Connection is being made for. 
247       * 
248       * @param _password the database Password 
249       */ 
250      public void setPassword(String _password) { 
251          password = _password; 
252      } 
253   
254      /** 
255       * Sets this classes instance variable, url, for this database url. * 
256       * The url is in the form of jdbc:subprotocol:subname * 
257       * 
258       * @param _url the database url 
259       */ 
260      public void setUrl(String _url) { 
261          url = _url; 
262      } 
263   
264      /** 
265       * Sets the name of the instance variable, driver, which this class is 
266       * loadeding. * This is the string representation of the driver being 
267       * loaded to make the connection to the database. * 
268       * 
269       * @param _driver the driver name 
270       */ 
271      public void setDriver(String _driver) { 
272          driver = _driver; 
273      } 
274   
275      /** 
276       * Sets this classes instance variable, tablename, for the current 
277       * database tablename. * 
278       * 
279       * @param _tablename the database tablename 
280       */ 
281      public void setTableName(String _tablename) { 
282          tablename = _tablename; 
283      } 
284   
285      /** 
286       * Constructor. 
287       */ 
288      public SqlBean() { 
289      } 
290   
291      /** 
292       * Loads specified driver and initializes the Connection to this 
293       * Database. * <p>Loads the driver and Connects to the Database * 
294       * <br>Retrieves and sets Database/Connection Information as follows: * 
295       * <br>&nbsp;&nbsp;&nbsp MetaData of this Database * 
296       * <br>&nbsp;&nbsp;&nbsp    Read Only Property * <br>&nbsp;&nbsp;&nbsp  Uses 
297       * Local Files Property * <br>&nbsp;&nbsp;&nbsp Driver Name Used for 
298       * the Connection * <br>&nbsp;&nbsp;&nbsp   Database Product Name * 
299       * <br>&nbsp;&nbsp;&nbsp    Table Types in this Database 
300       */ 
301      public void init() { 
302          try { 
303   
304              Class.forName(driver); 
305              c = DriverManager.getConnection(url, userId, password); 
306              dbmd = c.getMetaData(); 
307              catalogName = c.getCatalog(); 
308              isReadOnly = c.isReadOnly(); 
309              usesLocalFiles = dbmd.usesLocalFiles(); 
310              driverName = dbmd.getDriverName(); 
311              productName = dbmd.getDatabaseProductName(); 
312              rs_tabletypes = dbmd.getTableTypes(); 
313              catalogSeparator = dbmd.getCatalogSeparator(); 
314   
315   
316          } catch (ClassNotFoundException e) { 
317              println(e); 
318          } catch (SQLException e) { 
319              print(e); 
320          } 
321          System.out.println("Opened Connection:" + url); 
322      } 
323   
324      /** 
325       * Prints information about this database connection. * <p> <br>Prints 
326       * the following information: <br>&nbsp;&nbsp;&nbsp The name of this 
327       * database product * <br>&nbsp;&nbsp;&nbsp This Connection's current 
328       * catalog name * <br>&nbsp;&nbsp;&nbsp Is this connection in read-only 
329       * mode * <br>&nbsp;&nbsp;&nbsp Does this database store tables in a 
330       * local files * <br>&nbsp;&nbsp;&nbsp  The name of this JDBC driver * 
331       * <br>&nbsp;&nbsp;&nbsp    The SQL keywords of this database * 
332       * <br>&nbsp;&nbsp;&nbsp    The table types of all the tables in this 
333       * database * <br>&nbsp;&nbsp;&nbsp The names of all the tables in this 
334       * database * <br>&nbsp;&nbsp;&nbsp The names of all the non-system 
335       * tables in this database 
336       */ 
337      public void printDataBaseInfo() { 
338          println("*****"); 
339          println("productName=" + productName); 
340          println("*****"); 
341          println("catalogName=" + catalogName); 
342          println("*****"); 
343          try { 
344              println("allProceduresAreCallable=" + 
345                      dbmd.allProceduresAreCallable()); 
346          } catch (SQLException e) { 
347              e.printStackTrace(); 
348          } 
349          println("is ReadOnly=" + getReadOnly()); 
350          println("*****"); 
351          println("usesLocalFiles=" + getUsesLocalFiles()); 
352          println("*****"); 
353          println("driverName=" + driverName); 
354          println("*****"); 
355          println("Non SL92 keywords:"); 
356          println(getKeyWords()); 
357          println("*****"); 
358          println("TableTypes:"); 
359          print(getTableTypes()); 
360          println("*****"); 
361          println("TableNames - All:"); 
362          println(getTableNames()); 
363          println("*****"); 
364          println("TableNames - NonSystem:"); 
365          println(getNonMSysTables()); 
366   
367   
368      } 
369   
370      /** 
371       * Prints information about this current ResultSet.  <p> <br>Prints 
372       * the following information: <br>&nbsp;&nbsp;&nbsp The column names 
373       * (fields) of this database * <br>&nbsp;&nbsp;&nbsp The type name of 
374       * the columns (fields) used by this database 
375       * 
376       * @param _rs the current ResultSet 
377       */ 
378      public void printResultSetInfo(ResultSet _rs) { 
379          println("*****"); 
380          println("Column Names:"); 
381          println(getTableFields(getResultSetMetaData(_rs))); 
382          println("*****"); 
383          println("Column Types:"); 
384          println(getColumnTypeNames(getResultSetMetaData(_rs))); 
385          println("*****"); 
386          println("Number of Rows:"); 
387          println(Integer.toString((getNumberofRows(getRows(_rs))))); 
388          println("*****"); 
389          println("Print The First Row:"); 
390   
391      } 
392   
393      /** 
394       * Closes the connections to this database. 
395       */ 
396      public void close() { 
397   
398          try { 
399   
400              rs.close(); 
401              rs_tabletypes.close(); 
402              statement.close(); 
403              c.close(); 
404   
405              System.out.println("closed connection"); 
406          } catch (SQLException e) { 
407              print(e); 
408          } 
409      } 
410   
411      /** 
412       * Creates a Result Set based on an sql query. * 
413       * 
414       * @param sql the sql query 
415       * @return the ResultSet 
416       */ 
417      public ResultSet query(String sql) { 
418   
419          try { 
420              statement = c.createStatement(); 
421              currentquery = sql; 
422              return statement.executeQuery(sql); 
423          } catch (SQLException e) { 
424              print(e); 
425          } 
426          return null; 
427      } 
428   
429      /** 
430       * Gets the MetaData for a specified ResultSet. * 
431       * 
432       * @param _rs the ResultSet 
433       * @return the ResultSetMetaData 
434       */ 
435      public ResultSetMetaData getResultSetMetaData(ResultSet _rs) { 
436          try { 
437              return _rs.getMetaData(); 
438          } catch (SQLException e) { 
439              print(e); 
440          } 
441          return null; 
442      } 
443   
444      /** 
445       * Gets the number of columns in a ResultSet. * 
446       * 
447       * @param _rsmd the ResultSetMetaData 
448       * @return number of Columns (fields) 
449       */ 
450      public int getColumnCount(ResultSetMetaData _rsmd) { 
451          try { 
452              return _rsmd.getColumnCount(); 
453          } catch (SQLException e) { 
454              print(e); 
455          } 
456          return 0; 
457      } 
458   
459      /** 
460       * Gets the keywords associated with this database. * 
461       * 
462       * @return the keywords 
463       */ 
464   
465      public String getKeyWords() { 
466   
467          try { 
468              return dbmd.getSQLKeywords(); 
469          } catch (SQLException e) { 
470              print(e); 
471          } 
472          return null; 
473      } 
474   
475      /** 
476       * Gets the database types of the columns in a ResultSet. * These are 
477       * the type name used by this database. If the column type is a 
478       * user-defined type, * then a fully-qualified type name is returned. 
479       * * 
480       * 
481       * @param _rsmd the ResultSetMetaData 
482       * @return the column types 
483       */ 
484   
485      public String[] getColumnTypeNames(ResultSetMetaData _rsmd) { 
486   
487          int count = getColumnCount(_rsmd); 
488   
489          String sa [] = new String[count]; 
490          try { 
491              for (int i = 0; i < sa.length; i++) { 
492                  sa[i] = _rsmd.getColumnTypeName(i + 1); 
493              } 
494          } catch (SQLException e) { 
495              print(e); 
496          } 
497          return sa; 
498      } 
499   
500      /** 
501       * Converts a row in a ResultSet to a String. * 
502       * 
503       * @param _rs the ResultSet pointed to a particular row * @return the 
504       *            contents of the ResultSet 
505       */ 
506      public String[] getRowAsString(ResultSet _rs) { 
507   
508          int N = getColumnCount(getResultSetMetaData(_rs)); 
509          String s[] = new String[N]; 
510          try { 
511              for (int i = 0; i < N; i++) 
512                  s[i] = _rs.getString(i + 1); 
513          } catch (SQLException e) { 
514              print(e); 
515          } 
516          return s; 
517      } 
518   
519      /** 
520       * Converts a ResultSet to a Vector of Strings. * 
521       * 
522       * @param _rs the ResultSet 
523       * @return the vector containing the ResultSet with each row as a 
524       *         String 
525       */ 
526   
527      public Vector getRows(ResultSet _rs) { 
528          Vector v = new Vector(); 
529          while (nextRow(_rs)) 
530              v.addElement(getRowAsString(_rs)); 
531          return v; 
532      } 
533   
534      /** 
535       * Returns the size of a vector. Used with the getRows() method that 
536       * converts a ResultSet to a vector. * 
537       * 
538       * @param v the Vector 
539       * @return the number of rows 
540       */ 
541      public int getNumberofRows(Vector v) { 
542          return v.size(); 
543      } 
544   
545      /** 
546       * Moves to the top of this RecordSet. 
547       * 
548       * @param _rs the ResultSet 
549       */ 
550      public void moveToTop(ResultSet _rs) { 
551          try { 
552              //_rs.beforeFirst(); 
553              throw new SQLException("Not implemented until jdk 1.2"); 
554          } catch (SQLException e) { 
555              print(e); 
556          } 
557      } 
558   
559      /** 
560       * Prints the contents of a provided ResultSet. 
561       * 
562       * @param _rs the ResultSet 
563       */ 
564      public void print(ResultSet _rs) { 
565          String cn[] = getTableFields(getResultSetMetaData(_rs)); 
566          println(cn); 
567          for (boolean more = false; more; more = nextRow(_rs)) 
568              println(getRowAsString(_rs)); 
569      } 
570   
571      /** 
572       * Prints the contents of a provided Object. * Uses the toString() 
573       * method for the provided object. 
574       * 
575       * @param o the Object 
576       */ 
577   
578      public void println(Object o) { 
579   
580          System.out.println(o); 
581      } 
582   
583      /** 
584       * Prints the contents of a String array. 
585       * 
586       * @param s an array of string to be printed 
587       */ 
588   
589      public void println(String s[]) { 
590   
591          for (int i = 0; i < s.length; i++) 
592              System.out.print(s[i] + '\t'); 
593          System.out.println(); 
594   
595      } 
596   
597      /** 
598       * Prints messages about this SQL Exception. * 
599       * 
600       * @param ex the exception 
601       */ 
602   
603      private void print(SQLException ex) { 
604          println("\n*** SQLException caught ***\n"); 
605          while (ex != null) { 
606              println("SQLState: " + ex.getSQLState()); 
607              println("Message: " + ex.getMessage()); 
608              println("Vendor: " + ex.getErrorCode()); 
609              ex = ex.getNextException(); 
610              println(""); 
611          } 
612          ex.printStackTrace(); 
613      } 
614   
615   
616      /** 
617       * Moves to the next row of a provided ResultSet. * 
618       * 
619       * @param _rs the ResultSet 
620       */ 
621      public boolean nextRow(ResultSet _rs) { 
622          try { 
623              return _rs.next(); 
624          } catch (SQLException e) { 
625              return false; 
626          } 
627      } 
628   
629      /** 
630       * Gets the names of the columns (fields) in a provided ResultSet. * 
631       * 
632       * @param _rsmd the ResultSetMetaData 
633       * @return the table names 
634       */ 
635      public String[] getTableFields(ResultSetMetaData _rsmd) { 
636   
637          String s [] = new String[getColumnCount(_rsmd)]; 
638          try { 
639              for (int i = 1; i <= s.length; i++) 
640                  s[i - 1] = _rsmd.getColumnLabel(i); 
641          } catch (SQLException e) { 
642              print(e); 
643          } 
644          return s; 
645      } 
646   
647      /** 
648       * Gets this DataBaseMetaData object. 
649       * 
650       * @return this DataBaseMetaData 
651       */ 
652   
653      public DatabaseMetaData getDatabaseMetaData() { 
654   
655          return dbmd; 
656      } 
657   
658      /** 
659       * Process an SQL INSERT, DELETE or UPDATE statement string. * 
660       * Additionally, this could be an SQL statement that returns nothing 
661       * such as SQL DDL statments. * 
662       * 
663       * @param sql the SQL INSERT, UPDATE or DELETE statement or an SQL 
664       *            statement that returns nothing 
665       */ 
666   
667      public void modifyDatabase(String sql) { 
668          try { 
669              Statement s = c.createStatement(); 
670              s.executeUpdate(sql); 
671              println("UPDATE SUCCESSFUL"); 
672              println("SQL Statment= " + sql); 
673          } catch (SQLException e) { 
674              println("UPDATE NOT SUCCESSFUL"); 
675              println("SQL Statment= " + sql); 
676              print(e); 
677          } 
678      } 
679   
680      /** 
681       * Main entry point for application. 
682       * 
683       * @param args the command line arguments 
684       */ 
685   
686      public static void main(String args[]) { 
687          testSqlBean(); 
688      } 
689   
690      private static void testSqlBean() { 
691          SqlBean sb = new SqlBean(); 
692          sb.setUrl("jdbc:odbc:addresses"); 
693          sb.setDriver("sun.jdbc.odbc.JdbcOdbcDriver"); 
694          sb.setUserId(""); 
695          sb.setPassword(""); 
696          sb.println("Calling Init Method"); 
697          sb.init(); 
698          sb.println("****************"); 
699          sb.println("Calling printDataBaseInfo Method"); 
700          sb.printDataBaseInfo(); 
701          sb.setTableName("mailing"); 
702          sb.println("****************"); 
703          sb.println("Calling printResultSetInfo Method for Table Name: " 
704                  + sb.getTableName()); 
705          sb.printResultSetInfo( 
706                  sb.query("SELECT * FROM " + sb.getTableName())); 
707   
708          sb.println("****************"); 
709          sb.println("Calling modifyDatabase Method for Table Name: " + 
710                  sb.getTableName()); 
711          for (int i = 0; i < 100; i++) { 
712              sb.modifyDatabase("INSERT INTO " 
713                      + 
714                      sb.getTableName() 
715                      + 
716                      "(FirstName,LastName) VALUES " 
717                      + 
718                      "('vegg#" + 
719                      i + 
720                      "','Fresh Produce');"); 
721          } 
722          sb.println("****************"); 
723          sb.println("Calling Method to Print the Result Set for Table Name: " + 
724                  sb.getTableName()); 
725          //sb.print(sb.query("SELECT CategoryID,CategoryName, Description FROM " + sb.getTableName())); 
726          //sb.setTableName("Employees"); 
727          //sb.println("****************"); 
728          //sb.println("Calling Method to Print the Result Set for Table Name: " + sb.getTableName()); 
729          //sb.print(sb.query("SELECT EmployeeID, LastName, FirstName FROM " + sb.getTableName())); 
730          //sb.close(); 
731      } 
732   
733  }