You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@empire-db.apache.org by fr...@apache.org on 2010/01/11 08:34:31 UTC
svn commit: r897777 - in
/incubator/empire-db/trunk/empire-db-codegen/src/main:
java/org/apache/empire/db/codegen/ java/org/apache/empire/db/codegen/util/
resources/templates/
Author: francisdb
Date: Mon Jan 11 07:34:30 2010
New Revision: 897777
URL: http://svn.apache.org/viewvc?rev=897777&view=rev
Log:
EMPIREDB-69 Codegen Many Table Patterns, Template Folder in Config, and many more
(still needs a review)
Modified:
incubator/empire-db/trunk/empire-db-codegen/src/main/java/org/apache/empire/db/codegen/CodeGenConfig.java
incubator/empire-db/trunk/empire-db-codegen/src/main/java/org/apache/empire/db/codegen/CodeGenParser.java
incubator/empire-db/trunk/empire-db-codegen/src/main/java/org/apache/empire/db/codegen/CodeGenWriter.java
incubator/empire-db/trunk/empire-db-codegen/src/main/java/org/apache/empire/db/codegen/util/ParserUtil.java
incubator/empire-db/trunk/empire-db-codegen/src/main/resources/templates/Database.vm
Modified: incubator/empire-db/trunk/empire-db-codegen/src/main/java/org/apache/empire/db/codegen/CodeGenConfig.java
URL: http://svn.apache.org/viewvc/incubator/empire-db/trunk/empire-db-codegen/src/main/java/org/apache/empire/db/codegen/CodeGenConfig.java?rev=897777&r1=897776&r2=897777&view=diff
==============================================================================
--- incubator/empire-db/trunk/empire-db-codegen/src/main/java/org/apache/empire/db/codegen/CodeGenConfig.java (original)
+++ incubator/empire-db/trunk/empire-db-codegen/src/main/java/org/apache/empire/db/codegen/CodeGenConfig.java Mon Jan 11 07:34:30 2010
@@ -53,6 +53,12 @@
* name of the target folder
*/
private String targetFolder = "target/generated/db";
+
+ /**
+ * name of the template folder
+ */
+ private String templateFolder = "src/main/resources/templates";
+
/**
* name of the target package
*/
@@ -261,7 +267,15 @@
public void setTargetFolder(String targetFolder) {
this.targetFolder = targetFolder;
}
+
+ public String getTemplateFolder() {
+ return templateFolder;
+ }
+ public void setTemplateFolder(String templateFolder) {
+ this.templateFolder = templateFolder;
+ }
+
public String getPackageName() {
return packageName;
}
Modified: incubator/empire-db/trunk/empire-db-codegen/src/main/java/org/apache/empire/db/codegen/CodeGenParser.java
URL: http://svn.apache.org/viewvc/incubator/empire-db/trunk/empire-db-codegen/src/main/java/org/apache/empire/db/codegen/CodeGenParser.java?rev=897777&r1=897776&r2=897777&view=diff
==============================================================================
--- incubator/empire-db/trunk/empire-db-codegen/src/main/java/org/apache/empire/db/codegen/CodeGenParser.java (original)
+++ incubator/empire-db/trunk/empire-db-codegen/src/main/java/org/apache/empire/db/codegen/CodeGenParser.java Mon Jan 11 07:34:30 2010
@@ -22,6 +22,7 @@
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Types;
import java.util.ArrayList;
@@ -126,58 +127,51 @@
*/
private void populateDatabase(DBDatabase db) throws SQLException {
ResultSet tables = null;
- ResultSet views = null;
try{
this.dbMeta = con.getMetaData();
- // Get table metadata
- tables = dbMeta.getTables(
- config.getDbCatalog(),
- config.getDbSchema(),
- config.getDbTablePattern(),
- new String[] { "TABLE" });
- // Get view metadata
- views = dbMeta.getTables(
- config.getDbCatalog(),
- config.getDbSchema(),
- config.getDbTablePattern(),
- new String[] { "VIEW" });
+ String[] tablePatterns = {null}; // Could be null, so start that way.
+ if(config.getDbTablePattern() != null)
+ tablePatterns = config.getDbTablePattern().split(","); // Support a comma separated list of table patterns (i.e. specify a list of table names in the config file).
- // Add all tables
- int tableCount = 0;
- while (tables.next()) {
- String tableName = tables.getString("TABLE_NAME");
- // Ignore system tables containing a '$' symbol (required for Oracle!)
- if (tableName.indexOf('$') >= 0) {
- log.info("Ignoring system table " + tableName);
- continue;
- }
- log.info("TABLE: " + tableName);
- DBTable table = new DBTable(tableName, db);
- populateTable(table);
- tableCount++;
- }
-
- // Add all views
+ int tableCount = 0; // Moved to be outside table pattern loop.
int viewCount = 0;
- while (views.next()) {
- String viewName = views.getString("TABLE_NAME");
- // Ignore system tables containing a '$' symbol (required for Oracle!)
- if (viewName.indexOf('$') >= 0) {
- log.info("Ignoring system table " + viewName);
- continue;
+ for(String pattern : tablePatterns){
+
+ // Get table metadata
+ tables = dbMeta.getTables(
+ config.getDbCatalog(),
+ config.getDbSchema(),
+ pattern.trim(),
+ new String[] { "TABLE", "VIEW" });
+
+ // Add all tables and views
+ while (tables.next()) {
+ String tableName = tables.getString("TABLE_NAME");
+ String tableType = tables.getString("TABLE_TYPE");
+ // Ignore system tables containing a '$' symbol (required for Oracle!)
+ if (tableName.indexOf('$') >= 0) {
+ log.info("Ignoring system table " + tableName);
+ continue;
+ }
+ log.info(tableType + ": " + tableName);
+ if(tableType.equalsIgnoreCase("VIEW")){
+ InMemoryView view = new InMemoryView(tableName, db);
+ populateView(view);
+ viewCount++;
+ } else {
+ DBTable table = new DBTable(tableName, db);
+ populateTable(table);
+ tableCount++;
+ }
}
- log.info("VIEW: " + viewName);
- InMemoryView view = new InMemoryView(viewName, db);
- populateView(view);
- viewCount++;
- }
+ }
- if (tableCount==0) {
+ if (tableCount==0 && viewCount==0) {
// getTables returned no result
String info = "catalog="+config.getDbCatalog();
info += "/ schema="+config.getDbSchema();
info += "/ pattern="+config.getDbTablePattern();
- log.warn("DatabaseMetaData.getTables() returned no tables! Please check parameters: "+info);
+ log.warn("DatabaseMetaData.getTables() returned no tables or views! Please check parameters: "+info);
}
} finally {
DBUtil.close(tables, log);
@@ -272,8 +266,46 @@
if (rs.getString("IS_NULLABLE").equalsIgnoreCase("NO"))
required = true;
+ // The following is a hack for MySQL which currently gets sent a string "CURRENT_TIMESTAMP" from the Empire-db driver for MySQL.
+ // This will avoid the driver problem because CURRENT_TIMESTAMP in the db will just do the current datetime.
+ // Essentially, Empire-db needs the concept of default values of one type that get mapped to another.
+ // In this case, MySQL "CURRENT_TIMESTAMP" for Types.TIMESTAMP needs to emit from the Empire-db driver the null value and not "CURRENT_TIMESTAMP".
+ if(rs.getInt("DATA_TYPE") == Types.TIMESTAMP && defaultValue != null && defaultValue.equals("CURRENT_TIMESTAMP")){
+ required = false; // It is in fact not required even though MySQL schema is required because it has a default value. Generally, should Empire-db emit (required && defaultValue != null) to truly determine if a column is required?
+ defaultValue = null; // If null (and required per schema?) MySQL will apply internal default value.
+ }
+
+ // AUTOINC indicator is not in java.sql.Types but rather meta data from DatabaseMetaData.getColumns()
+ // getEmpireDataType() above is not enough to support AUTOINC as it will only return DataType.INTEGER
+ DataType originalType = empireType;
+ ResultSetMetaData metaData = rs.getMetaData();
+ int colCount = metaData.getColumnCount();
+ String colName;
+ for (int i = 1; i <= colCount; i++) {
+ colName = metaData.getColumnName(i);
+ // MySQL matches on IS_AUTOINCREMENT column.
+ // SQL Server matches on TYPE_NAME column with identity somewhere in the string value.
+ if ((colName.equalsIgnoreCase("IS_AUTOINCREMENT") && rs.getString(i).equalsIgnoreCase("YES")) ||
+ (colName.equals("TYPE_NAME") && rs.getString(i).matches(".*(?i:identity).*"))){
+ empireType = DataType.AUTOINC;
+
+ }
+ }
+
+ // Move from the return statement below so we can add
+ // some AUTOINC meta data to the column to be used by
+ // the ParserUtil and ultimately the template.
log.info("\tCOLUMN:\t" + name + " ("+empireType+")");
- return t.addColumn(name, empireType, colSize, required, defaultValue);
+ DBTableColumn col = t.addColumn(name, empireType, colSize, required, defaultValue);
+
+ // We still need to know the base data type for this AUTOINC
+ // because the Record g/setters need to know this, right?
+ // So, let's add it as meta data every time the column is AUTOINC
+ // and reference it in the template.
+ if(empireType.equals(DataType.AUTOINC))
+ col.setAttribute("AutoIncDataType", originalType);
+ return col;
+
}
/**
Modified: incubator/empire-db/trunk/empire-db-codegen/src/main/java/org/apache/empire/db/codegen/CodeGenWriter.java
URL: http://svn.apache.org/viewvc/incubator/empire-db/trunk/empire-db-codegen/src/main/java/org/apache/empire/db/codegen/CodeGenWriter.java?rev=897777&r1=897776&r2=897777&view=diff
==============================================================================
--- incubator/empire-db/trunk/empire-db-codegen/src/main/java/org/apache/empire/db/codegen/CodeGenWriter.java (original)
+++ incubator/empire-db/trunk/empire-db-codegen/src/main/java/org/apache/empire/db/codegen/CodeGenWriter.java Mon Jan 11 07:34:30 2010
@@ -67,7 +67,6 @@
private static final Log log = LogFactory.getLog(CodeGenWriter.class);
// Templates
- public static final String TEMPLATE_PATH = "src/main/resources/templates/";
public static final String DATABASE_TEMPLATE = "Database.vm";
public static final String BASE_TABLE_TEMPLATE = "BaseTable.vm";
public static final String TABLE_TEMPLATE = "Table.vm";
@@ -183,9 +182,10 @@
context.put("nestTables", config.isNestTables());
context.put("baseTableClassName", config.getTableBaseName());
context.put("nestViews", config.isNestViews());
+ context.put("templateFolder", config.getTemplateFolder());
context.put("baseViewClassName", config.getViewBaseName());
- writeFile(file, TEMPLATE_PATH + "/" + DATABASE_TEMPLATE, context);
+ writeFile(file, config.getTemplateFolder() + "/" + DATABASE_TEMPLATE, context);
return file;
}
@@ -194,7 +194,7 @@
VelocityContext context = new VelocityContext();
context.put("tablePackageName", config.getTablePackageName());
context.put("baseTableClassName", config.getTableBaseName());
- writeFile(file, TEMPLATE_PATH + "/" + BASE_TABLE_TEMPLATE, context);
+ writeFile(file, config.getTemplateFolder() + "/" + BASE_TABLE_TEMPLATE, context);
return file;
}
@@ -209,7 +209,7 @@
context.put("dbClassName", config.getDbClassName());
context.put("nestTables", config.isNestTables());
context.put("table", table);
- writeFile(file, TEMPLATE_PATH + "/" + TABLE_TEMPLATE, context);
+ writeFile(file, config.getTemplateFolder() + "/" + TABLE_TEMPLATE, context);
return file;
}
@@ -218,7 +218,7 @@
VelocityContext context = new VelocityContext();
context.put("viewPackageName", config.getViewPackageName());
context.put("baseViewClassName", config.getViewBaseName());
- writeFile(file, TEMPLATE_PATH + "/" + BASE_VIEW_TEMPLATE, context);
+ writeFile(file, config.getTemplateFolder() + "/" + BASE_VIEW_TEMPLATE, context);
return file;
}
@@ -233,7 +233,7 @@
context.put("dbClassName", config.getDbClassName());
context.put("nestViews", config.isNestViews());
context.put("view", view);
- writeFile(file, TEMPLATE_PATH + "/" + VIEW_TEMPLATE, context);
+ writeFile(file, config.getTemplateFolder() + "/" + VIEW_TEMPLATE, context);
return file;
}
@@ -245,7 +245,7 @@
context.put("tablePackageName", config.getTablePackageName());
context.put("recordPackageName", config.getRecordPackageName());
context.put("baseTableClassName", config.getTableBaseName());
- writeFile(file, TEMPLATE_PATH + "/" + BASE_RECORD_TEMPLATE, context);
+ writeFile(file, config.getTemplateFolder() + "/" + BASE_RECORD_TEMPLATE, context);
return file;
}
@@ -267,7 +267,7 @@
.isCreateRecordProperties());
context.put("table", table);
- writeFile(file, TEMPLATE_PATH + "/" + RECORD_TEMPLATE, context);
+ writeFile(file, config.getTemplateFolder() + "/" + RECORD_TEMPLATE, context);
return file;
}
Modified: incubator/empire-db/trunk/empire-db-codegen/src/main/java/org/apache/empire/db/codegen/util/ParserUtil.java
URL: http://svn.apache.org/viewvc/incubator/empire-db/trunk/empire-db-codegen/src/main/java/org/apache/empire/db/codegen/util/ParserUtil.java?rev=897777&r1=897776&r2=897777&view=diff
==============================================================================
--- incubator/empire-db/trunk/empire-db-codegen/src/main/java/org/apache/empire/db/codegen/util/ParserUtil.java (original)
+++ incubator/empire-db/trunk/empire-db-codegen/src/main/java/org/apache/empire/db/codegen/util/ParserUtil.java Mon Jan 11 07:34:30 2010
@@ -18,10 +18,14 @@
*/
package org.apache.empire.db.codegen.util;
+import java.lang.reflect.Method;
+import java.util.HashSet;
+
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.empire.data.DataType;
import org.apache.empire.db.DBColumn;
+import org.apache.empire.db.DBRecord;
import org.apache.empire.db.DBTable;
import org.apache.empire.db.DBTableColumn;
import org.apache.empire.db.codegen.CodeGenConfig;
@@ -35,10 +39,26 @@
private CodeGenConfig config;
+ private static HashSet<String> dbrecMethodNames;
+
public ParserUtil(CodeGenConfig config) {
this.config = config;
}
+
+ public static HashSet<String> getDBRecordMethodNames(){
+ // some g/setters like getState() can conflict with DBRecord
+ // methods. To check for conflicts, we'll need to know
+ // the method names.
+ if(dbrecMethodNames == null){
+ Method[] dbrecMethods = DBRecord.class.getMethods();
+ dbrecMethodNames = new HashSet<String>(dbrecMethods.length);
+ for(Method method : dbrecMethods){
+ dbrecMethodNames.add(method.getName());
+ }
+ }
+ return dbrecMethodNames;
+ }
/**
* Returns the java table class name for a given table name.
@@ -53,7 +73,7 @@
*/
public String getViewClassName(String viewName) {
return config.getViewClassPrefix() + javaClassName(viewName)
- + config.getTableClassSuffix();
+ + config.getViewClassSuffix();
}
/**
@@ -77,7 +97,7 @@
*/
public String getMutatorName(DBColumn c) {
- return deriveMutatorName(c.getName());
+ return deriveMutatorName(c.getName(), getJavaType(c).equalsIgnoreCase("Boolean"));
}
/**
@@ -128,6 +148,16 @@
*/
public String getJavaType(DBColumn c) {
DataType type = getDataType(c);
+ // We added the attribute of original datatype to AUTOINC columns
+ // in CodeGenParser.addColumn(). Now we need to use it so that
+ // the g/setters deal with the right Java type.
+
+ // If the original data type was not set as an attribute for some
+ // reason this will just fall through to the bottom and
+ // return "Byte[]", so no problem.
+ if (type.equals(DataType.AUTOINC) && null != c.getAttribute("AutoIncDataType"))
+ type = (DataType)c.getAttribute("AutoIncDataType");
+
if (type.equals(DataType.INTEGER))
return "Long";
else if (type.equals(DataType.TEXT))
@@ -185,6 +215,12 @@
private static String javaClassName(String name) {
StringBuilder sb = new StringBuilder();
sb.append(Character.toUpperCase(name.charAt(0)));
+ // Tables might already be camel case. Let's skip this if no '_' anywhere.
+ if(name.substring(1).indexOf('_') <= 0) {
+ if(name.length() > 1)
+ sb.append(name.substring(1));
+ return sb.toString();
+ }
boolean upperCase = false;
for (int i = 1; i < name.length(); i++)
{
@@ -210,14 +246,32 @@
* @return
*/
private static String deriveAccessorName(String attribute, boolean isBoolean) {
+ return deriveRecordMethodName(attribute, isBoolean, true);
+ }
+
+ // We need to alter both getter and setter if the method name will
+ // conflict with existing methods DBRecord. This will check both
+ // so that getter and setter have matching suffixes if one or
+ // the other conflicts with an existing method.
+ private static String deriveRecordMethodName(String attribute, boolean isBoolean, boolean isGetter) {
attribute = deriveAttributeName(attribute);
StringBuilder sb = new StringBuilder();
- if (isBoolean)
- sb.append("is");
- else
- sb.append("get");
sb.append(Character.toUpperCase(attribute.charAt(0)));
sb.append(attribute.substring(1));
+
+ StringBuilder sbGet = new StringBuilder();
+ if (isBoolean)
+ sbGet.append("is");
+ else
+ sbGet.append("get");
+ sbGet.append(sb);
+
+ StringBuilder sbSet = new StringBuilder("set");
+ sbSet.append(sb);
+ sb = isGetter ? sbGet : sbSet;
+ HashSet<String> names = getDBRecordMethodNames();
+ if(names.contains(sbGet.toString()) || names.contains(sbSet.toString()))
+ sb.append("Column"); // Any change will resolve the conflict.
return sb.toString();
}
@@ -227,13 +281,8 @@
* @param attribute
* @return
*/
- private static String deriveMutatorName(String attribute) {
- attribute = deriveAttributeName(attribute);
- StringBuilder sb = new StringBuilder();
- sb.append("set");
- sb.append(Character.toUpperCase(attribute.charAt(0)));
- sb.append(attribute.substring(1));
- return sb.toString();
+ private static String deriveMutatorName(String attribute, boolean isBoolean) {
+ return deriveRecordMethodName(attribute, isBoolean, false);
}
/**
Modified: incubator/empire-db/trunk/empire-db-codegen/src/main/resources/templates/Database.vm
URL: http://svn.apache.org/viewvc/incubator/empire-db/trunk/empire-db-codegen/src/main/resources/templates/Database.vm?rev=897777&r1=897776&r2=897777&view=diff
==============================================================================
--- incubator/empire-db/trunk/empire-db-codegen/src/main/resources/templates/Database.vm (original)
+++ incubator/empire-db/trunk/empire-db-codegen/src/main/resources/templates/Database.vm Mon Jan 11 07:34:30 2010
@@ -131,13 +131,13 @@
#if($nestTables == true)
#foreach ($table in $database.tables)
- #parse( "src/main/resources/templates/Table.vm" )
+ #parse( "$templateFolder/Table.vm" )
#end
#end
#if($nestViews == true)
#foreach ($view in $database.views)
- #parse( "src/main/resources/templates/View.vm" )
+ #parse( "$templateFolder/View.vm" )
#end
#end