undisclosed
2023-10-19 b88616bc6e37ecba2404360426113f72f6c94b30
commit | author | age
c387eb 1 /*
U 2  *  BaseLink - Generic object relational mapping
07913e 3  *  Copyright (C) 2011-2020  Ulrich Hilger, http://uhilger.de
c387eb 4  *
U 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   /**
07913e 41    * Generate a database transfer object (DTO) for a table
U 42    * 
c387eb 43    * @param pm  an object to be used for database access
U 44    * @param schemaName name of database schema that contains the table 
45    * @param tableName name of table to create DAO for
c16126 46    * @return java source code of DTO
c387eb 47    */
07913e 48   public String generateDTO(PersistenceManager pm, String schemaName, String tableName) {
c387eb 49     String indentation = "  ";
U 50     //String indent = "";
51     StringBuilder code = new StringBuilder();
52     Connection c = null;
53     try {
54       c = pm.getConnection();
55       code.append("@DBTable(name=\"");
56       code.append(schemaName.toLowerCase());
57       code.append(".");
58       code.append(tableName.toLowerCase());
59       code.append("\")");
60       code.append(System.lineSeparator());
61       code.append("@DBPrimaryKey({\"");
62       List<List<String>> keys = getPrimaryKeys(pm, c, schemaName, tableName);
63       String colName = null;
64       for(int row = 1; row < keys.size(); row++) {
65         if(row > 1) {
66           code.append(",\"");
67         }
68         colName = keys.get(row).get(3).toLowerCase();
69         code.append(colName);
70         code.append("\"");
71       }
72       code.append("})");
73       code.append(System.lineSeparator());
74       code.append("public class ");
75       code.append(tableName.toLowerCase());
76       code.append(" {");
77       code.append(System.lineSeparator());
78   
79       /*
80         columns.size(): Anzahl Zeilen
81         columns.get(0).size(): Anzahl Felder
82         Column Name: columns.get(1).get(3)
83         Datentyp: columns.get(1).get(4)
84       */    
85       List<List<String>> columns = getColumns(pm, c, schemaName, tableName);
86       String fieldname = null;
87       String typename = null;
88       int type = -1;
89   
90       // class members
91       for(int row = 1; row < columns.size(); row++) {
92         type = Integer.parseInt(columns.get(row).get(4));
93         fieldname = columns.get(row).get(3).toLowerCase();
94         typename = getTypeName(type);
95         code.append(indentation);
96         code.append("private ");
97         code.append(typename);
98         code.append(" ");
99         code.append(fieldname);
100         code.append(";");
101         code.append(System.lineSeparator());      
102       }
103       
104       // setters and getters
105       for(int row = 1; row < columns.size(); row++) {
106         type = Integer.parseInt(columns.get(row).get(4));
107         fieldname = columns.get(row).get(3).toLowerCase();
108         typename = getTypeName(type);
109         code.append(System.lineSeparator());
110         code.append(System.lineSeparator());
111         code.append(indentation);
112         code.append("public void set");
113         code.append(fieldname);
114         code.append("(");
115         code.append(typename);
116         code.append(" wert) {");
117         code.append(System.lineSeparator());
118         code.append(indentation);
119         code.append(indentation);
120         code.append(fieldname);
121         code.append(" = wert;");
122         code.append(System.lineSeparator());
123         code.append(indentation);
124         code.append("}");
125         code.append(System.lineSeparator());
126         code.append(System.lineSeparator());
127         code.append(indentation);
128         //  @DBColumn(name="dc_content", type=DBColumn.Type.BLOB)
129         code.append("@DBColumn(name = \"");
130         code.append(fieldname);
131         if(type == java.sql.Types.BLOB) {
132           code.append("\", type=DBColumn.Type.BLOB)");
133         } else {
134           code.append("\")");
135         }
136         code.append(System.lineSeparator());
137         code.append(indentation);
138         code.append("public ");
139         code.append(typename);
140         code.append(" get");
141         code.append(fieldname);
142         code.append("() {");
143         code.append(System.lineSeparator());
144         code.append(indentation);
145         code.append(indentation);
146         code.append("return ");
147         code.append(fieldname);
148         code.append(";");
149         code.append(System.lineSeparator());
150         code.append(indentation);
151         code.append("}");
152       }
153       
154       code.append(System.lineSeparator());
155       code.append("}");
156       c.close();
157       c = null;
158     } catch (Exception ex) {
159       logger.log(Level.SEVERE, ex.getMessage(), ex);
160     } finally {
161       pm.closeConnectionFinally(c);
162     }
163     return code.toString();    
164   }
165   
166   /**
07913e 167    * Generate a database transfer object (DTO) for a table
U 168    * 
169    * This method is kept for compatibility reasons, it maps to 
170    * <code>generateDTO</code>.
171    * 
172    * @param pm  an object to be used for database access
173    * @param schemaName name of database schema that contains the table 
174    * @param tableName name of table to create DAO for
c16126 175    * @return java source code of DTO
07913e 176    */
U 177   public String generateDAO(PersistenceManager pm, String schemaName, String tableName) {
178     return generateDTO(pm, schemaName, tableName);
179   }
180   
181   /**
c387eb 182    * Get a description of the columns of a database table
U 183    * 
184    * @param pm  an object to be used for database access
185    * @param c  the database connection that has been opened for this action
186    * @param schemaName name of database schema that contains the table 
187    * @param tableName name of table to get column descriptions for
188    * @return column description as returned by java.sql.DatabaseMetaData, 
189    * transformed to a List of rows, each row being a List of Strings, each 
190    * String being a field of the column description for respective table 
191    * column
192    */
193   public List<List<String>> getColumns(PersistenceManager pm, Connection c, String schemaName, String tableName) {
194     List<List<String>> list = null;
195     ResultSet rs = null;
196     try {
197       DatabaseMetaData meta = c.getMetaData();
198       rs = meta.getColumns(null, schemaName, tableName, null);
199       list = pm.toList(rs, DONT_INCLUDE_BLOBS);
200       rs.close();
201       rs = null;
202     } catch (Exception ex) {
203       logger.log(Level.SEVERE, ex.getMessage(), ex);
204     } finally {
205       pm.closeResultSetFinally(rs);
206     }
207     return list;
208   }
209   
210   /**
211    * Get a description of the primary keys of a database table
212    * 
213    * @param pm  an object to be used for database access
214    * @param c  the database connection that has been opened for this action
215    * @param schemaName name of database schema that contains the table 
216    * @param tableName name of table to get primary key descriptions for
217    * @return primary key description as returned by java.sql.DatabaseMetaData, 
218    * transformed to a List of rows, each row being a List of Strings, each 
219    * String being a field of the primary key description for respective table
220    */
221   public List<List<String>> getPrimaryKeys(PersistenceManager pm, Connection c, String schemaName, String tableName) {
222     List<List<String>> list = null;
223     ResultSet rs = null;
224     try {
225       DatabaseMetaData meta = c.getMetaData();
226       rs = meta.getPrimaryKeys(null, schemaName, tableName);
227       list = pm.toList(rs, DONT_INCLUDE_BLOBS);
228       rs.close();
229       rs = null;
230     } catch (Exception ex) {
231       logger.log(Level.SEVERE, ex.getMessage(), ex);
232     } finally {
233       pm.closeResultSetFinally(rs);
234     }
235     return list;
236   }
237   
238   
239   /**
240    * Convert a java.sql.Type to a Java type name 
241    * @param type  SQL type to be converted
242    * @return Java type name, e.g. String oder int; 
243    * if the type can not be converted without an 
244    * individually developed conversion 'tbd' is 
245    * returned with the SQL type name included, e.g. 
246    * tbd_CLOB, tbd_DISTINCT, etc.
247    */
248   private String getTypeName(int type) {
249     String typename = null;
250     switch(type) {
251       case java.sql.Types.ARRAY:
252         typename = "tbd_ARRAY";
253         break;
254       case java.sql.Types.BIGINT:
255         typename = "long";
256         break;
257       case java.sql.Types.BINARY:
258         typename = "byte[]";
259         break;
260       case java.sql.Types.BIT:
261         typename = "tbd_BIT";
262         break;
263       case java.sql.Types.BLOB:
264         typename = "String";
265         break;
266       case java.sql.Types.BOOLEAN:
267         typename = "boolean";
268         break;
269       case java.sql.Types.CHAR:
270         typename = "String";
271         break;
272       case java.sql.Types.CLOB:
273         typename = "tbd_CLOB";
274         break;
275       case java.sql.Types.DATALINK:
276         typename = "tbd_DATALINK";
277         break;
278       case java.sql.Types.DATE:
279         typename = "java.sql.Date";
280         break;
281       case java.sql.Types.DECIMAL:
282         typename = "float";
283         break;
284       case java.sql.Types.DISTINCT:
285         typename = "tbd_DISTINCT";
286         break;
287       case java.sql.Types.DOUBLE:
288         typename = "double";
289         break;
290       case java.sql.Types.FLOAT:
291         typename = "float";
292         break;
293       case java.sql.Types.INTEGER:
294         typename = "int";
295         break;
296       case java.sql.Types.JAVA_OBJECT:
297         typename = "Object";
298         break;
299       case java.sql.Types.LONGVARCHAR:
300         typename = "String";
301         break;
302       case java.sql.Types.NCHAR:
303         typename = "String";
304         break;
305       case java.sql.Types.NCLOB:
306         typename = "tbd_NCLOB";
307         break;
308       case java.sql.Types.NULL:
309         typename = "tbd_NULL";
310         break;
311       case java.sql.Types.NUMERIC:
312         typename = "float";
313         break;
314       case java.sql.Types.NVARCHAR:
315         typename = "String";
316         break;
317       case java.sql.Types.OTHER:
318         typename = "tbd_OTHER";
319         break;
320       case java.sql.Types.REAL:
321         typename = "float";
322         break;
323       case java.sql.Types.REF:
324         typename ="tbd_REF";
325         break;
326       case java.sql.Types.ROWID:
327         typename = "tbd_ROWID";
328         break;
329       case java.sql.Types.SMALLINT:
330         typename = "integer";
331         break;
332       case java.sql.Types.SQLXML:
333         typename = "tbd_SQLXML";
334         break;
335       case java.sql.Types.STRUCT:
336         typename = "tbd_STRUCT";
337         break;
338       case java.sql.Types.TIME:
339         typename = "tbd_TIME";
340         break;
341       case java.sql.Types.TIMESTAMP:
24feb5 342         typename = "java.sql.Timestamp";
c387eb 343         break;
U 344       case java.sql.Types.TINYINT:
345         typename = "integer";
346         break;
347       case java.sql.Types.VARBINARY:
348         typename = "tbd_VARBINARY";
349         break;
350       case java.sql.Types.VARCHAR:
351         typename = "String";
352         break;
353       default:
354         typename = "tbd_UNDEFINED";
355         break;
356     }
357     return typename;
358   }  
359 }