ulrich
2017-01-15 eccba685782f7159d57e14c937e7b9c459b2371a
commit | author | age
c387eb 1 /*
U 2  *  BaseLink - Generic object relational mapping
3  *  Copyright (C) 2011  Ulrich Hilger, http://uhilger.de
4  *
5  *  This program is free software: you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation, either version 3 of the License, or
8  *  (at your option) any later version.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with this program.  If not, see http://www.gnu.org/licenses/
17  */
18
19 package de.uhilger.baselink;
20
21 import java.util.*;
22 import java.util.logging.*;
23 import java.sql.*;
24
25 /**
26  * Utility methods for the BaseLink package
27  * 
28  * @author Copyright (c) Ulrich Hilger, <a href="http://uhilger.de">http://uhilger.de</a>
29  * @author Published under the terms and conditions of
30  * the <a href="http://www.gnu.org/licenses/" target="_blank">GNU General Public License</a>
31  * @version 1, October 31, 2014
32  */
33 public class Util {
34   
35   private static final Logger logger = Logger.getLogger(Util.class.getName());
36   
37   public static final boolean DO_INCLUDE_BLOBS = true;
38   public static final boolean DONT_INCLUDE_BLOBS = false;
39   
40   /**
41    * Generate a database access object (DAO) for a table
42    * @param pm  an object to be used for database access
43    * @param schemaName name of database schema that contains the table 
44    * @param tableName name of table to create DAO for
45    * @return java source code of DAO
46    */
47   public String generateDAO(PersistenceManager pm, String schemaName, String tableName) {
48     String indentation = "  ";
49     //String indent = "";
50     StringBuilder code = new StringBuilder();
51     Connection c = null;
52     try {
53       c = pm.getConnection();
54       code.append("@DBTable(name=\"");
55       code.append(schemaName.toLowerCase());
56       code.append(".");
57       code.append(tableName.toLowerCase());
58       code.append("\")");
59       code.append(System.lineSeparator());
60       code.append("@DBPrimaryKey({\"");
61       List<List<String>> keys = getPrimaryKeys(pm, c, schemaName, tableName);
62       String colName = null;
63       for(int row = 1; row < keys.size(); row++) {
64         if(row > 1) {
65           code.append(",\"");
66         }
67         colName = keys.get(row).get(3).toLowerCase();
68         code.append(colName);
69         code.append("\"");
70       }
71       code.append("})");
72       code.append(System.lineSeparator());
73       code.append("public class ");
74       code.append(tableName.toLowerCase());
75       code.append(" {");
76       code.append(System.lineSeparator());
77   
78       /*
79         columns.size(): Anzahl Zeilen
80         columns.get(0).size(): Anzahl Felder
81         Column Name: columns.get(1).get(3)
82         Datentyp: columns.get(1).get(4)
83       */    
84       List<List<String>> columns = getColumns(pm, c, schemaName, tableName);
85       String fieldname = null;
86       String typename = null;
87       int type = -1;
88   
89       // class members
90       for(int row = 1; row < columns.size(); row++) {
91         type = Integer.parseInt(columns.get(row).get(4));
92         fieldname = columns.get(row).get(3).toLowerCase();
93         typename = getTypeName(type);
94         code.append(indentation);
95         code.append("private ");
96         code.append(typename);
97         code.append(" ");
98         code.append(fieldname);
99         code.append(";");
100         code.append(System.lineSeparator());      
101       }
102       
103       // setters and getters
104       for(int row = 1; row < columns.size(); row++) {
105         type = Integer.parseInt(columns.get(row).get(4));
106         fieldname = columns.get(row).get(3).toLowerCase();
107         typename = getTypeName(type);
108         code.append(System.lineSeparator());
109         code.append(System.lineSeparator());
110         code.append(indentation);
111         code.append("public void set");
112         code.append(fieldname);
113         code.append("(");
114         code.append(typename);
115         code.append(" wert) {");
116         code.append(System.lineSeparator());
117         code.append(indentation);
118         code.append(indentation);
119         code.append(fieldname);
120         code.append(" = wert;");
121         code.append(System.lineSeparator());
122         code.append(indentation);
123         code.append("}");
124         code.append(System.lineSeparator());
125         code.append(System.lineSeparator());
126         code.append(indentation);
127         //  @DBColumn(name="dc_content", type=DBColumn.Type.BLOB)
128         code.append("@DBColumn(name = \"");
129         code.append(fieldname);
130         if(type == java.sql.Types.BLOB) {
131           code.append("\", type=DBColumn.Type.BLOB)");
132         } else {
133           code.append("\")");
134         }
135         code.append(System.lineSeparator());
136         code.append(indentation);
137         code.append("public ");
138         code.append(typename);
139         code.append(" get");
140         code.append(fieldname);
141         code.append("() {");
142         code.append(System.lineSeparator());
143         code.append(indentation);
144         code.append(indentation);
145         code.append("return ");
146         code.append(fieldname);
147         code.append(";");
148         code.append(System.lineSeparator());
149         code.append(indentation);
150         code.append("}");
151       }
152       
153       code.append(System.lineSeparator());
154       code.append("}");
155       c.close();
156       c = null;
157     } catch (Exception ex) {
158       logger.log(Level.SEVERE, ex.getMessage(), ex);
159     } finally {
160       pm.closeConnectionFinally(c);
161     }
162     return code.toString();    
163   }
164   
165   /**
166    * Get a description of the columns of a database table
167    * 
168    * @param pm  an object to be used for database access
169    * @param c  the database connection that has been opened for this action
170    * @param schemaName name of database schema that contains the table 
171    * @param tableName name of table to get column descriptions for
172    * @return column description as returned by java.sql.DatabaseMetaData, 
173    * transformed to a List of rows, each row being a List of Strings, each 
174    * String being a field of the column description for respective table 
175    * column
176    */
177   public List<List<String>> getColumns(PersistenceManager pm, Connection c, String schemaName, String tableName) {
178     List<List<String>> list = null;
179     ResultSet rs = null;
180     try {
181       DatabaseMetaData meta = c.getMetaData();
182       rs = meta.getColumns(null, schemaName, tableName, null);
183       list = pm.toList(rs, DONT_INCLUDE_BLOBS);
184       rs.close();
185       rs = null;
186     } catch (Exception ex) {
187       logger.log(Level.SEVERE, ex.getMessage(), ex);
188     } finally {
189       pm.closeResultSetFinally(rs);
190     }
191     return list;
192   }
193   
194   /**
195    * Get a description of the primary keys of a database table
196    * 
197    * @param pm  an object to be used for database access
198    * @param c  the database connection that has been opened for this action
199    * @param schemaName name of database schema that contains the table 
200    * @param tableName name of table to get primary key descriptions for
201    * @return primary key description as returned by java.sql.DatabaseMetaData, 
202    * transformed to a List of rows, each row being a List of Strings, each 
203    * String being a field of the primary key description for respective table
204    */
205   public List<List<String>> getPrimaryKeys(PersistenceManager pm, Connection c, String schemaName, String tableName) {
206     List<List<String>> list = null;
207     ResultSet rs = null;
208     try {
209       DatabaseMetaData meta = c.getMetaData();
210       rs = meta.getPrimaryKeys(null, schemaName, tableName);
211       list = pm.toList(rs, DONT_INCLUDE_BLOBS);
212       rs.close();
213       rs = null;
214     } catch (Exception ex) {
215       logger.log(Level.SEVERE, ex.getMessage(), ex);
216     } finally {
217       pm.closeResultSetFinally(rs);
218     }
219     return list;
220   }
221   
222   
223   /**
224    * Convert a java.sql.Type to a Java type name 
225    * @param type  SQL type to be converted
226    * @return Java type name, e.g. String oder int; 
227    * if the type can not be converted without an 
228    * individually developed conversion 'tbd' is 
229    * returned with the SQL type name included, e.g. 
230    * tbd_CLOB, tbd_DISTINCT, etc.
231    */
232   private String getTypeName(int type) {
233     String typename = null;
234     switch(type) {
235       case java.sql.Types.ARRAY:
236         typename = "tbd_ARRAY";
237         break;
238       case java.sql.Types.BIGINT:
239         typename = "long";
240         break;
241       case java.sql.Types.BINARY:
242         typename = "byte[]";
243         break;
244       case java.sql.Types.BIT:
245         typename = "tbd_BIT";
246         break;
247       case java.sql.Types.BLOB:
248         typename = "String";
249         break;
250       case java.sql.Types.BOOLEAN:
251         typename = "boolean";
252         break;
253       case java.sql.Types.CHAR:
254         typename = "String";
255         break;
256       case java.sql.Types.CLOB:
257         typename = "tbd_CLOB";
258         break;
259       case java.sql.Types.DATALINK:
260         typename = "tbd_DATALINK";
261         break;
262       case java.sql.Types.DATE:
263         typename = "java.sql.Date";
264         break;
265       case java.sql.Types.DECIMAL:
266         typename = "float";
267         break;
268       case java.sql.Types.DISTINCT:
269         typename = "tbd_DISTINCT";
270         break;
271       case java.sql.Types.DOUBLE:
272         typename = "double";
273         break;
274       case java.sql.Types.FLOAT:
275         typename = "float";
276         break;
277       case java.sql.Types.INTEGER:
278         typename = "int";
279         break;
280       case java.sql.Types.JAVA_OBJECT:
281         typename = "Object";
282         break;
283       case java.sql.Types.LONGVARCHAR:
284         typename = "String";
285         break;
286       case java.sql.Types.NCHAR:
287         typename = "String";
288         break;
289       case java.sql.Types.NCLOB:
290         typename = "tbd_NCLOB";
291         break;
292       case java.sql.Types.NULL:
293         typename = "tbd_NULL";
294         break;
295       case java.sql.Types.NUMERIC:
296         typename = "float";
297         break;
298       case java.sql.Types.NVARCHAR:
299         typename = "String";
300         break;
301       case java.sql.Types.OTHER:
302         typename = "tbd_OTHER";
303         break;
304       case java.sql.Types.REAL:
305         typename = "float";
306         break;
307       case java.sql.Types.REF:
308         typename ="tbd_REF";
309         break;
310       case java.sql.Types.ROWID:
311         typename = "tbd_ROWID";
312         break;
313       case java.sql.Types.SMALLINT:
314         typename = "integer";
315         break;
316       case java.sql.Types.SQLXML:
317         typename = "tbd_SQLXML";
318         break;
319       case java.sql.Types.STRUCT:
320         typename = "tbd_STRUCT";
321         break;
322       case java.sql.Types.TIME:
323         typename = "tbd_TIME";
324         break;
325       case java.sql.Types.TIMESTAMP:
326         typename = "tbd_TIMESTAMP";
327         break;
328       case java.sql.Types.TINYINT:
329         typename = "integer";
330         break;
331       case java.sql.Types.VARBINARY:
332         typename = "tbd_VARBINARY";
333         break;
334       case java.sql.Types.VARCHAR:
335         typename = "String";
336         break;
337       default:
338         typename = "tbd_UNDEFINED";
339         break;
340     }
341     return typename;
342   }  
343 }