From 662d8f9eaede744806f592e96561b8b7083c52f3 Mon Sep 17 00:00:00 2001 From: garthpatil Date: Wed, 12 Sep 2012 13:27:20 -0700 Subject: [PATCH 01/11] commit creating repo --- README.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 From ff3472d5415cc3cc1480d969fc6def11e11ee1af Mon Sep 17 00:00:00 2001 From: garthpatil Date: Wed, 12 Sep 2012 14:28:38 -0700 Subject: [PATCH 02/11] initial commit of code and simple doc --- README.md | 20 + pom.xml | 64 + run.sh | 3 + src/config/test.properties | 173 +++ .../net/sourceforge/sql2java/CodeWriter.java | 539 +++++++ .../java/net/sourceforge/sql2java/Column.java | 635 ++++++++ .../net/sourceforge/sql2java/Database.java | 341 +++++ .../java/net/sourceforge/sql2java/Main.java | 115 ++ .../sourceforge/sql2java/StringUtilities.java | 527 +++++++ .../java/net/sourceforge/sql2java/Table.java | 376 +++++ .../sourceforge/sql2java/UserCodeParser.java | 172 +++ .../sql2java/ant/GenerationTask.java | 24 + .../sql2java/ant/SchemaCheckTask.java | 29 + .../sql2java/ant/TableGenerationTask.java | 35 + .../sql2java/ant/UtilsGenerationTask.java | 30 + .../sql2java/maven/Sql2JavaMojo.java | 64 + .../velocity/global/basemanager.java.vm | 570 ++++++++ .../velocity/global/cachingmanager.java.vm | 113 ++ .../templates/velocity/global/daobean.java.vm | 15 + .../velocity/global/daomanager.java.vm | 52 + .../velocity/global/managerfactory.java.vm | 29 + .../velocity/includes/header.include.vm | 8 + .../includes/table.variables.include.vm | 21 + .../templates/velocity/table/bean.java.vm | 247 ++++ .../velocity/table/comparator.java.vm | 104 ++ .../templates/velocity/table/listener.java.vm | 47 + .../templates/velocity/table/manager.java.vm | 1280 +++++++++++++++++ 27 files changed, 5633 insertions(+) create mode 100644 pom.xml create mode 100755 run.sh create mode 100644 src/config/test.properties create mode 100755 src/main/java/net/sourceforge/sql2java/CodeWriter.java create mode 100644 src/main/java/net/sourceforge/sql2java/Column.java create mode 100755 src/main/java/net/sourceforge/sql2java/Database.java create mode 100755 src/main/java/net/sourceforge/sql2java/Main.java create mode 100755 src/main/java/net/sourceforge/sql2java/StringUtilities.java create mode 100755 src/main/java/net/sourceforge/sql2java/Table.java create mode 100755 src/main/java/net/sourceforge/sql2java/UserCodeParser.java create mode 100644 src/main/java/net/sourceforge/sql2java/ant/GenerationTask.java create mode 100644 src/main/java/net/sourceforge/sql2java/ant/SchemaCheckTask.java create mode 100644 src/main/java/net/sourceforge/sql2java/ant/TableGenerationTask.java create mode 100644 src/main/java/net/sourceforge/sql2java/ant/UtilsGenerationTask.java create mode 100644 src/main/java/net/sourceforge/sql2java/maven/Sql2JavaMojo.java create mode 100644 src/main/resources/templates/velocity/global/basemanager.java.vm create mode 100755 src/main/resources/templates/velocity/global/cachingmanager.java.vm create mode 100644 src/main/resources/templates/velocity/global/daobean.java.vm create mode 100755 src/main/resources/templates/velocity/global/daomanager.java.vm create mode 100644 src/main/resources/templates/velocity/global/managerfactory.java.vm create mode 100755 src/main/resources/templates/velocity/includes/header.include.vm create mode 100755 src/main/resources/templates/velocity/includes/table.variables.include.vm create mode 100755 src/main/resources/templates/velocity/table/bean.java.vm create mode 100755 src/main/resources/templates/velocity/table/comparator.java.vm create mode 100755 src/main/resources/templates/velocity/table/listener.java.vm create mode 100644 src/main/resources/templates/velocity/table/manager.java.vm diff --git a/README.md b/README.md index e69de29..2c7ba9d 100644 --- a/README.md +++ b/README.md @@ -0,0 +1,20 @@ +# sql2java # + +This is a fork of a project on SourceForge by the same name . It is heavily modified from the original version. I started using this around 2005 as a quick & dirty way to generate Java beans and data access managers from a SQL database. Here I am, 7+ years later, still using it, totally underwhelmed with the state of ORM tools like Hibernate. The short of it is, if you know SQL, there's no reason to use an ORM that hides it from you. If you don't, well, you're probably screwed on the performance front, so you should switch to Ruby On Rails anyways, as you'll be much more productive. The only thing that looks interesting to me these days is JDBI which puts nice Java idioms on top of SQL and JDBC. Otherwise, for trivial projects where I'm just ripping strings in and out of databases, I'll probably keep using this for another 7 years. + +This differs from the original project in the following ways: +- Build uses Maven. Will be packaged as a Maven plugin in the future. +- No more web widgets or factories. Just beans and managers. +- Manager class is gone. BaseManager now take a DataSource directly. +- Uses generics to make the code more concise (and requires Java 1.5) +- Not sure if anything but MySQL and HSQL support works anymore. PostgreSQL did work a while ago, but haven't checked in a bit. + +To try it out, edit src/config/test.properties to reflect your databases's properties, and run: + +./run.sh src/config/test.properties + +Which just uses Maven exec:java to run: + +mvn -e exec:java -Dexec.classpathScope="runtime" -Dexec.mainClass="net.sourceforge.sql2java.Main" -Dexec.args="src/config/test.properties" + +Generated classes will appear in target/generated-sources/ or wherever you configured in src/config/test.properties. There is a log at target/velocity.log that will tell you if anything failed, and running Maven with the -e flag should be somewhat informative. \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..09724af --- /dev/null +++ b/pom.xml @@ -0,0 +1,64 @@ + + + 4.0.0 + net.sourceforge + sql2java-maven-plugin + maven-plugin + 1.0-SNAPSHOT + sql2java-maven-plugin + + + + + + + org.apache.ant + ant + [1.7.0,) + + + java2html + j2h + [1.2,) + + + velocity + velocity + 1.3.1 + + + velocity + velocity-dep + 1.3.1 + + + hsqldb + hsqldb + 1.8.0.10 + runtime + + + mysql + mysql-connector-java + [5.1,) + runtime + + + org.apache.maven + maven-plugin-api + 2.0 + + + junit + junit + 3.8.1 + test + + + + + UTF-8 + + + diff --git a/run.sh b/run.sh new file mode 100755 index 0000000..37428a0 --- /dev/null +++ b/run.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +mvn -e exec:java -Dexec.classpathScope="runtime" -Dexec.mainClass="net.sourceforge.sql2java.Main" -Dexec.args="$1" diff --git a/src/config/test.properties b/src/config/test.properties new file mode 100644 index 0000000..d164654 --- /dev/null +++ b/src/config/test.properties @@ -0,0 +1,173 @@ +# +# SAMPLE PROPERTIES FILE FOR SQL2JAVA +# + + +#---------------------------------------------- +# (1/7) CONFIGURE YOUR DATABASE ACCESS +#---------------------------------------------- +#jdbc.driver=org.hsqldb.jdbcDriver +#jdbc.url=jdbc:hsqldb:hsql://localhost +#jdbc.username=sa +#jdbc.password= +#jdbc.schema= + +jdbc.driver=com.mysql.jdbc.Driver +jdbc.url=jdbc:mysql://localhost:3306/schema_here +jdbc.username= +jdbc.password= +jdbc.schema=schema_here + + +#------------------------------------------------- +# (2/7) CONFIGURE RETRIEVAL OF AUTO GENERATED KEY +#------------------------------------------------- +# For those who do not want to read below, please simply pick up the +# configuration associated with your database. +# +# More explanation: +# When you save a bean whose primary key is numeric and has no value set, +# we assume that you want sql2java to retrieve a key's value generated +# on the database side. +# +# generatedkey.retrieve can take 4 values: +# +# auto - the standard approach when you have a JDBC 3.0 driver. +# +# before - the key's value is retrieved before inserting the record. +# +# after - the key's value is retrieved after inserting the record +# +# none - the key's value is never retrieved, frankly I doubt you +# want this configuration +# +# If you set it to before or after you also need to configure the +# autogeneratedkey.statement properties. +# is replaced at code generation time by the table name. +# You may adjust this properties to fit your own naming convention. +# +# PICK THE CONFIGURATION ASSOCIATED WITH YOUR DATABASE +# (or create one, but in that case let us know so we can add it here... :-) +# +#-- HSQL ------ +#generatedkey.retrieve=after +#generatedkey.statement=CALL IDENTITY() +# +#-- IF YOU USE A JDBC 3.0 DRIVER (works with mysql, ORACLE 9, etc..) ------ +generatedkey.retrieve=auto +generatedkey.statement= +# +#-- MYSQL (without jdbc 3.0 driver) ------ +#generatedkey.retrieve=after +#generatedkey.statement=SELECT last_insert_id() +# +#-- POSTGRESQL ------ +#generatedkey.retrieve=before +#generatedkey.statement=SELECT nextval('
_SEQ') +# + + +#---------------------------------------------- +# (3/7) GENERATED SOURCE CODE +#---------------------------------------------- + +# Package name for the generated source code +mgrwriter.package=net.sql2java.sample.database + +# Destination of the generated source code (package hierarchy is preserved) +mgrwriter.destdir=target/generated-sources + +# Property file to use when initializing Velocity +#mgrwriter.velocityprops=somefile + +# templates (you can generate java files, jsp, etc...) + +mgrwriter.templates.loadingpath=target/classes/templates/velocity/global, \ + target/classes/templates/velocity/table, \ + target/classes/templates/velocity/includes + +mgrwriter.templates.perschema= daomanager.java.vm, \ + basemanager.java.vm, \ + cachingmanager.java.vm + +mgrwriter.templates.pertable= bean.java.vm, \ + manager.java.vm + +# sets a prefix to prepend to all generated classes +# useful if you are worried about namespace collision with reserved words +# or java.lang classes +#mgrwriter.classprefix= + + +#----------------------------------------------- +# (4/7) JDBC TYPES Mapping +#----------------------------------------------- +# +# jdbc DATE mapping can be: +# java.sql.Date +# java.util.Date +jdbc2java.date=java.util.Date + +# jdbc TIME mapping can be: +# java.sql.Time +# java.util.Date +jdbc2java.time=java.util.Date + +# jdbc TIMESTAMP mappning can be: +# java.sql.Timestamp +# java.util.Date +jdbc2java.timestamp=java.util.Date + + +#----------------------------------------------- +# (5/7) FILTER OUT CERTAIN TABLES +#----------------------------------------------- +# +# COMMA SEPARATED list of table types to be mapped +# Commonly seen types are TABLE, VIEW, SYSTEM TABLE, SYNONYM +jdbc.tabletypes=TABLE + +# Table name pattern of tables to be mapped to classes. +# available wildcard: % +# defaults to % +# You can specify several patterns separated by commas. +jdbc.tablenamepattern=% + +# SPACE SEPARATED list of tables to include or exclude. If you specify both, +# the include list will take priority. If these fields are left commented out, +# all tables in the specified schema will get mapped to classes +#mgrwriter.include=Testing +#mgrwriter.exclude= + + +#----------------------------------------------- +# (6/7) CONFIGURE OPTIMISTIC LOCK +#----------------------------------------------- +# optimisticlock.type can take 2 values: +# none - the optimistic lock mechanism is disabled (default). +# timestamp - the optimistic lock column contains the System.currentTimeMillis() value. +# +# optimisticlock.column takes the column name used by optimistic lock mechanism in your database. +# If this column is not present in some table the optimistic lock is not applied there. +# the column mapping can be java.lang.Long or java.lang.String. +# (jdbc type size >= 13 characters) +optimisticlock.type=timestamp +optimisticlock.column=version_time + + +#----------------------------------------------- +# (7/7) ORGANISE YOUR SUBPACKAGES +#----------------------------------------------- +#subpackage.1.name=products.delivery +#subpackage.1.tables=delivery + +#subpackage.2.name=products.product +#subpackage.2.tables=product + +#subpackage.3.name=products.manufacturer +#subpackage.3.tables=manufacturer + +#subpackage.4.name=users +#subpackage.4.tables=customer, shipper, + + diff --git a/src/main/java/net/sourceforge/sql2java/CodeWriter.java b/src/main/java/net/sourceforge/sql2java/CodeWriter.java new file mode 100755 index 0000000..a1e1450 --- /dev/null +++ b/src/main/java/net/sourceforge/sql2java/CodeWriter.java @@ -0,0 +1,539 @@ +//$Id: CodeWriter.java,v 1.1 2005/10/12 18:44:24 framiere Exp $ + +package net.sourceforge.sql2java; + +//TODO: Add exception handling in this class for the VelocityEngine. + +import java.io.*; +import java.util.*; +import java.sql.Types; + +import org.apache.velocity.Template; +import org.apache.velocity.app.Velocity; +import org.apache.velocity.app.FieldMethodizer; +import org.apache.velocity.VelocityContext; +import org.apache.velocity.exception.*; + +// this class is a mess, would need some brushing, however the generated code is clean and +// that's what really matters +public class CodeWriter +{ + static protected Properties props; + + public static String MGR_CLASS="Manager"; + + protected static String dateClassName; + protected static String timeClassName; + protected static String timestampClassName; + + protected Database db; + protected Hashtable includeHash, excludeHash; + + protected String basePackage; + protected String destDir; + protected String optimisticLockType; + protected String optimisticLockColumn; + public String classPrefix; + + protected VelocityContext vc; + + public Table table; + protected VelocityContext current_vc; + + /////////////////////////////////////////////////////// + // CODE WRITER INIT + /////////////////////////////////////////////////////// + + /** The Default Constructor + * @author Kelvin Nishikawa + * @param props Properties for configuring this instance + */ + public CodeWriter (Database db, Properties props) { + try { + this.db = db; + this.props = props; + + dateClassName = props.getProperty("jdbc2java.date", "java.sql.Date"); + timeClassName = props.getProperty("jdbc2java.time", "java.sql.Time"); + timestampClassName = props.getProperty("jdbc2java.timestamp", "java.sql.Timestamp"); + + // Set properties + basePackage = props.getProperty("mgrwriter.package"); + classPrefix = props.getProperty("mgrwriter.classprefix"); + setDestinationFolder(props.getProperty("mgrwriter.destdir")); + + excludeHash = setHash(props.getProperty("mgrwriter.exclude")); + if (excludeHash.size() != 0) + System.out.println("Excluding the following tables: " + props.getProperty("mgrwriter.exclude")); + includeHash = setHash(props.getProperty("mgrwriter.include")); + if (includeHash.size() != 0) + System.out.println("Including only the following tables: " + props.getProperty("mgrwriter.include")); + + optimisticLockType = props.getProperty("optimisticlock.type", "none"); + optimisticLockColumn = props.getProperty("optimisticlock.column"); + + if(basePackage == null) + { + throw new Exception("Missing property: mgrwriter.package"); + } + + } catch (Exception e) { + //knishikawa - maybe this needs better exception handling for the Velocity inits + System.err.println("Threw an exception in the CodeWriter constructor:" + e.getMessage()); + e.printStackTrace(); + } + } + + + public void setDestinationFolder(String destDir) throws Exception + { + this.destDir = destDir; + if(destDir == null) + { + throw new Exception("Missing property: mgrwriter.destdir"); + } + + File dir = new File(destDir); + try { + dir.mkdirs(); + } catch (Exception e) { + // ignore + } + + if(!dir.isDirectory() || !dir.canWrite()) + { + throw new Exception("Cannot write to: " + destDir); + } + } + + + private Hashtable setHash(String str) + { + if(str == null || str.trim().equals("")) + return new Hashtable(); + else + { + Hashtable hash = new Hashtable(); + StringTokenizer st = new StringTokenizer(str); + while(st.hasMoreTokens()) + { + String val = st.nextToken().toLowerCase(); + hash.put(val, val); + } + + return hash; + } + } + + public boolean checkTable(Table table) throws Exception + { + System.out.println(" checking table " + table.getName() + " ..."); + boolean error = false; + Column primaryKeys[] = table.getPrimaryKeys(); + if (table.getColumns().length == 0) + { + System.err.println(" WARN : no column found !"); + error = false; + } + if (primaryKeys.length == 0) + { + System.err.println(" WARN : No primary key is defined on table " + table.getName()); + System.err.println(" Tables without primary key are not fully supported"); + error = false; + } + else + { + if (primaryKeys.length > 1) + { + System.err.print(" WARN : Composite primary key "); + for (int ii = 0; ii < primaryKeys.length; ii++) + System.err.print(primaryKeys[ii].getFullName() + ", "); + System.err.println(); + System.err.println(" Tables with composite primary key are not fully supported"); + } + else + { + Column pk = primaryKeys[0]; + String pkName = pk.getName(); + String normalKey = table.getName() + "_id"; + if (pkName.equalsIgnoreCase(normalKey) == false) + { + System.err.println(" WARN : primary key should of form _ID"); + System.err.println(" found " + pkName + " expected " + normalKey); + } + if (pk.isColumnNumeric() == false) + { + System.err.println(" WARN : primary key should be an integer "); + System.err.println(" found " + pk.getJavaType()); + } + } + } + return error; + } + + public void checkDatabase() throws Exception + { + System.out.println("Checking database tables"); + boolean error = false; + Table tables[] = db.getTables(); + for (int i = 0; i < tables.length; i++) + { + if (includeHash.size() != 0) + { + if (includeHash.get(tables[i].getName().toLowerCase()) != null) + { + if (excludeHash.get(tables[i].getName().toLowerCase()) == null) + { + boolean b = checkTable(tables[i]); + if (b == true) + error = true; + } + } + } + else + { + if (excludeHash.size() != 0) + { + if (excludeHash.get(tables[i].getName().toLowerCase()) == null) + { + boolean b = checkTable(tables[i]); + if (b == true) + error = true; + } + } + else + { + boolean b = checkTable(tables[i]); + if (b == true) + error = true; + } + } + } + if (error == true) + { + System.err.println(" Failed : at least one of the mandatory rule for sql2java is followed by your schema."); + System.err.println(" Please check the documentation for more information"); + System.exit(-1); + } + System.out.println(" Passed."); + } + + /////////////////////////////////////////////////////// + // CODE WRITER CORE + /////////////////////////////////////////////////////// + + /** The entry point for generating code. */ + public synchronized void process() throws Exception + { + if ("true".equalsIgnoreCase(Main.getProperty("check.database"))) + checkDatabase(); + + if ("true".equalsIgnoreCase(Main.getProperty("check.only.database"))) + return; + + // Init Velocity + Properties vprops = new Properties(); + vprops.put("runtime.log", "target/velocity.log"); + vprops.put("file.resource.loader.path", getProperty("mgrwriter.templates.loadingpath",".") ); + + Velocity.init(vprops); + vc = new VelocityContext(); + vc.put("CodeWriter", new FieldMethodizer( this )); + vc.put("codewriter", this ); + vc.put("pkg", basePackage); + vc.put("pkgPath", basePackage.replace('.', '/')); + vc.put("strUtil", StringUtilities.getInstance()); + current_vc = new VelocityContext(vc); + + System.out.println("Generation in folder " + destDir + " ..."); + String[] schema_templates = getPropertyExploded("mgrwriter.templates.perschema"); + for(int i=0; i 0 */ + public boolean hasRemarks() { + String remarks = table.getRemarks(); + if ( remarks != null ) if ( remarks.length() > 0 ) return true; + return false; + } + + /** Returns the current table's remarks. */ + public String getRemarks() { + return table.getRemarks(); + } + + /** Returns a db.getRelationTable( table ) as a list */ + public List getRelationTable() { + Table [] rtabs = db.getRelationTable(table); + List tables = new ArrayList(rtabs.length); + for ( int i = 0; i < rtabs.length; i++ ) tables.add(rtabs[i]); + return tables; + } + + /** Returns a table's linked tables as a list */ + public List getLinkedTables ( Table rTable ) { + Table[] ltabs = rTable.linkedTables(db, table); + List tables = new ArrayList(ltabs.length); + for ( int i = 0; i < ltabs.length; i++ ) tables.add(ltabs[i]); + return tables; + } + + /** Wrapper for the static Column method */ + public boolean isPresentLock( Collection cols ) { + Column [] columns = new Column[cols.size()]; + int i = 0; + Iterator iter = cols.iterator(); + while ( iter.hasNext() ) columns[i++] = (Column)iter.next(); + return Column.isPresentLock(columns, optimisticLockType, optimisticLockColumn); + } + + /** Find the column in the Collection that matches optimisticLockColumn */ + public Column getLockColumn(Collection cols) { + Iterator iter = cols.iterator(); + while ( iter.hasNext() ) { + Column col = (Column)iter.next(); + if ( col.getName().equalsIgnoreCase( optimisticLockColumn ) ) return col; + } + return null; + } + + /** public accessor for table */ + public Table getTable() { + return table; + } + + /** Check if a list contains an item that is equal() to a string */ + public boolean listContainsString( List list, String string ) { + Object obj = null; + for ( Iterator iter = list.iterator(); + iter.hasNext(); + obj = iter.next() ) { + if ( string.equals(obj) ) return true; + } + return false; + } + + + ////////////////////////////////////////////////////// + // PROPERTY UTILS + ////////////////////////////////////////////////////// + /** Convenience property chop method + * @author Kelvin Nishikawa + * @param key the property to get from this.props + * @return the associated value + */ + static public String getProperty(String key) + { + String s = props.getProperty(key); + return s!=null?s.trim():s; + } + + /** Convenience property chop method + * @author Kelvin Nishikawa + * @param key the property to get from this.props + * @param default_val the default value to return in case not found + * @return the associated value + */ + static public String getProperty(String key, String default_val) { + String s = props.getProperty(key,default_val); + return s!=null?s.trim():s; + } + + + /** + * Return as a String array the key's value. + */ + static public String[] getPropertyExploded(String key) + { + String v = getProperty(key); + if (v==null) { + return new String[0]; + } + ArrayList al = new ArrayList(); + + StringTokenizer st = new StringTokenizer(v, " ,;\t"); + while (st.hasMoreTokens()) { + al.add(st.nextToken().trim()); + } + + return (String[])al.toArray(new String[al.size()]); + } +} diff --git a/src/main/java/net/sourceforge/sql2java/Column.java b/src/main/java/net/sourceforge/sql2java/Column.java new file mode 100644 index 0000000..ed90e78 --- /dev/null +++ b/src/main/java/net/sourceforge/sql2java/Column.java @@ -0,0 +1,635 @@ +//$Id: Column.java,v 1.4 2005/10/17 09:09:59 framiere Exp $ + +package net.sourceforge.sql2java; + +import java.util.List; +import java.util.Vector; +import java.sql.Types; + +public class Column implements Cloneable { + + // List of possible mapped types. + public static final int M_ARRAY = 0; + public static final int M_BIGDECIMAL = 1; + public static final int M_BOOLEAN = 2; + public static final int M_BYTES = 3; + public static final int M_CLOB = 4; + public static final int M_SQLDATE =5 ; + public static final int M_UTILDATE =6 ; + public static final int M_DOUBLE = 7; + public static final int M_FLOAT = 8; + public static final int M_BLOB = 9; + public static final int M_INTEGER = 10; + public static final int M_LONG = 11; + public static final int M_REF = 12; + public static final int M_STRING =13 ; + public static final int M_TIME = 14; + public static final int M_TIMESTAMP = 15; + public static final int M_URL = 16; + public static final int M_OBJECT = 17; + + private String catalog, schema, tableName, name, remarks, defaultValue; + private int size, decDigits, radix, nullable, ordinal; + private short type; + private boolean isPrimaryKey; + private String strCheckingType = ""; + private Database db; + private List foreignKeys = new Vector(); + private List importedKeys = new Vector(); + + /** + */ + public String toString() + { + return "\n --------- " + tableName + "." + name + " --------- " + + "\n schema = " + schema + + "\n tableName = " + tableName + + "\n catalog = " + catalog + + "\n remarks = " + remarks + + "\n defaultValue = " + defaultValue + + "\n decDigits = " + decDigits + + "\n radix = " + radix + + "\n nullable = " + nullable + + "\n ordinal = " + ordinal + + "\n size = " + size + + "\n type = " + type + " " + + "\n isPrimaryKey = " + (isPrimaryKey ? "true":"false"); + } + + public void setCheckingType(String strValue){this.strCheckingType = strValue;} + public String getCheckingType(){return strCheckingType; } + public void setDatabase(Database db) { this.db = db; } + public void setCatalog(String catalog) { this.catalog = catalog; } + public void setSchema(String schema) { this.schema = schema; } + public void setTableName(String tableName) { this.tableName = tableName; } + public void setName(String name) { this.name = name; } + public void setType(short type) { this.type = type; } + public void setSize(int size) { this.size = size; } + public void setDecimalDigits(int decDigits) { this.decDigits = decDigits; } + public void setRadix(int radix) { this.radix = radix; } + public void setNullable(int nullable) { this.nullable = nullable; } + public void setRemarks(String remarks) { + if (remarks!=null) { + this.remarks = remarks.replaceAll("/\\*", "SLASH*").replaceAll("\\*/", "*SLASH"); + } + } + public void setDefaultValue(String defaultValue) { this.defaultValue = defaultValue; } + public void setOrdinalPosition(int ordinal) { this.ordinal = ordinal; } + public void isPrimaryKey(boolean isPrimaryKey) { this.isPrimaryKey = isPrimaryKey; } + + public String getCatalog() { return catalog; } + public String getSchema() { return schema; } + public String getTableName() { return tableName; } + public String getName() { return name; } + public short getType() { return type; } + public int getSize() { return size; } + public int getDecimalDigits() { return decDigits; } + public int getRadix() { return radix; } + public int getNullable() { return nullable; } + public String getNullableAsString() { return (getNullable() != 0 ? "nullable" : "null not allowed"); } + public String getRemarks() { return remarks==null?"":remarks; } + public String getDefaultValue() { return defaultValue==null?"":defaultValue; } + public int getOrdinalPosition() { return ordinal; } + public boolean isPrimaryKey() { return isPrimaryKey; } + public String getFullName() { return tableName + "." + getName(); } + public String getConstName() { return getName().toUpperCase(); } + + public Object clone() throws CloneNotSupportedException { + return super.clone(); + } + + private void tuoe() { + throw new UnsupportedOperationException("not supported yet: "+ getTableName() + "." + getName() + " " + getJavaTypeAsTypeName()); + } + + private void tiae() { + throw new IllegalArgumentException("No primary type associated: " + getTableName() + "." + getName() ); + } + + /** + * return internal type for the current column + */ + public int getMappedType() { + switch(getType()) { + case Types.ARRAY: return M_ARRAY; + case Types.BIGINT : return M_LONG; + case Types.BINARY : return M_BYTES; + case Types.BIT : return M_BOOLEAN; + case Types.BLOB : return M_BLOB; + case Types.BOOLEAN : return M_BOOLEAN; + case Types.CHAR : return M_STRING; + case Types.CLOB : return M_CLOB; + case Types.DATALINK : return M_URL; + case Types.DATE : + if (CodeWriter.dateClassName.equals("java.util.Date")) return M_UTILDATE; + if (CodeWriter.dateClassName.equals("java.sql.Date")) return M_SQLDATE; + tuoe(); + case Types.DECIMAL : return getDecimalDigits() > 0 ? M_BIGDECIMAL : M_LONG; + case Types.DISTINCT : return M_OBJECT; + case Types.DOUBLE : return M_DOUBLE; + case Types.FLOAT : return M_DOUBLE; + case Types.INTEGER :return M_INTEGER; + case Types.JAVA_OBJECT : return M_OBJECT; + case Types.LONGVARBINARY :return M_BYTES; + case Types.LONGVARCHAR : return M_STRING; + +// case Types.NULL : return M_NULL; + + case Types.NUMERIC : return getDecimalDigits() > 0 ? M_BIGDECIMAL : M_LONG; + case Types.OTHER : return M_OBJECT; + case Types.REAL : return M_FLOAT; + case Types.REF : return M_REF; + case Types.SMALLINT :return M_INTEGER; + case Types.STRUCT : return M_OBJECT; + case Types.TIME : + if (CodeWriter.timeClassName.equals("java.util.Date")) return M_UTILDATE; + if (CodeWriter.timeClassName.equals("java.sql.Time")) return M_TIME; + tuoe(); + case Types.TIMESTAMP : + if (CodeWriter.timestampClassName.equals("java.util.Date")) return M_UTILDATE; + if (CodeWriter.timestampClassName.equals("java.sql.Timestamp")) return M_TIMESTAMP; + tuoe(); + case Types.TINYINT :return M_INTEGER; + case Types.VARBINARY :return M_BYTES; + case Types.VARCHAR :return M_STRING; + default:tuoe(); + } + return -1; + } + + // Convernient helpers: + + /** + * return the java type of the current column + */ + public String getJavaType() + { + switch (getMappedType()) + { + case M_ARRAY: return "Array"; + case M_BIGDECIMAL: return "java.math.BigDecimal"; + case M_BOOLEAN: return "Boolean"; + case M_BYTES: return "byte[]"; + case M_CLOB: return "Clob"; + case M_SQLDATE: return "java.sql.Date"; + case M_UTILDATE: return "java.util.Date"; + case M_DOUBLE: return "Double"; + case M_FLOAT: return "Float"; + case M_INTEGER: return "Integer"; + case M_LONG: return "Long"; + case M_REF: return "Ref"; + case M_STRING: return "String"; + case M_TIME: return "java.sql.Time"; + case M_TIMESTAMP: return "java.sql.Timestamp"; + case M_URL: return "java.net.URL"; + case M_OBJECT: return "Object"; + } + return null; + } + + /** + * does this column has a primary java type like short, boolean instead of Integer and Boolean ? + */ + public boolean hasPrimaryType() + { + if (getJavaPrimaryType() == null) + return false; + return true; + } + + /** + * return the primary java type of the current column + * return null if no java primary type is available + */ + public String getJavaPrimaryType() throws IllegalArgumentException + { + int decimalDigits = getDecimalDigits(); + int type = getType(); + int size = getSize(); + if ((type == Types.DECIMAL || type == Types.NUMERIC) && decimalDigits == 0) { + if (size == 1) { + return "boolean"; + } + else if (size < 3) { + return "byte"; + } + else if (size < 5) { + return "short"; + } + else if (size < 10) { + return "int"; + } + else if (size < 19) { + return "long"; + } + else { + return "java.math.BigDecimal"; + } + } + switch (getMappedType()) + { + case M_BOOLEAN: return "boolean"; + case M_SQLDATE: return "long"; + case M_UTILDATE: return "long"; + case M_DOUBLE: return "double"; + case M_FLOAT: return "float"; + case M_INTEGER: return "int"; + case M_LONG: return "long"; + case M_TIME: return "long"; + case M_TIMESTAMP: return "long"; + default:break; + } + return null; + } + + /** + * return the string representation of the column type + */ + public String getJavaTypeAsTypeName() + { + switch (getType()) + { + case Types.ARRAY: return "Types.ARRAY"; + case Types.BIGINT : return "Types.BIGINT"; + case Types.BINARY : return "Types.BINARY"; + case Types.BIT : return "Types.BIT"; + case Types.BLOB : return "Types.BLOB"; + case Types.BOOLEAN : return "Types.BOOLEAN"; + case Types.CHAR : return "Types.CHAR"; + case Types.CLOB : return "Types.CLOB"; + case Types.DATALINK : return "Types.DATALINK"; + case Types.DATE : return "Types.DATE"; + case Types.DECIMAL : return "Types.DECIMAL"; + case Types.DISTINCT : return "Types.DISTINCT"; + case Types.DOUBLE : return "Types.DOUBLE"; + case Types.FLOAT : return "Types.FLOAT"; + case Types.INTEGER : return "Types.INTEGER"; + case Types.JAVA_OBJECT : return "Types.JAVA_OBJECT"; + case Types.LONGVARBINARY : return "Types.LONGVARBINARY"; + case Types.LONGVARCHAR : return "Types.LONGVARCHAR"; + case Types.NULL : return "Types.NULL"; + case Types.NUMERIC : return "Types.NUMERIC"; + case Types.OTHER : return "Types.OTHER"; + case Types.REAL : return "Types.REAL"; + case Types.REF : return "Types.REF"; + case Types.SMALLINT : return "Types.SMALLINT"; + case Types.STRUCT : return "Types.STRUCT"; + case Types.TIME : return "Types.TIME"; + case Types.TIMESTAMP : return "Types.TIMESTAMP"; + case Types.TINYINT : return "Types.TINYINT"; + case Types.VARBINARY : return "Types.VARBINARY"; + case Types.VARCHAR : return "Types.VARCHAR"; + default:tuoe(); + } + return null; + } + + /** + * is this column numeric ? + */ + public boolean isColumnNumeric() + { + switch (getMappedType()) + { + case M_DOUBLE: // fall through + case M_FLOAT: // fall through + case M_INTEGER: // fall through + case M_LONG: return true; + default: return false; + } + } + + /** + * is this column a string ? + */ + public boolean isString() + { + if (getMappedType() == M_STRING) + return true; + return false; + } + + /** + * does this type has a compareTo method ? + */ + public boolean hasCompareTo() throws Exception + { + switch(getMappedType()) + { + case M_ARRAY: return false; + case M_BIGDECIMAL: return true; + case M_BOOLEAN: return false; // USE EQUALS INSTEAD + case M_BYTES: return false; + case M_CLOB: return false; + case M_SQLDATE: return true; + case M_UTILDATE: return true; + case M_DOUBLE: return true; + case M_FLOAT: return true; + case M_INTEGER: return true; + case M_LONG: return true; + case M_REF: return false; + case M_STRING: return true; + case M_TIME: return true; + case M_TIMESTAMP: return true; + case M_URL: return false; + case M_OBJECT: return false; + default: return false; + } + } + + /** + * does this type can use equal instead of the compareTo method ? + */ + public boolean useEqualsInSetter() throws Exception + { + switch(getMappedType()) + { + case M_BOOLEAN: return true; + default: return false; + } + } + + /** + * return the resultSet get method for a given position + * the assumption is that the resultset variable is called rs + */ + public String getResultSetMethodObject(String pos) + { + return getResultSetMethodObject("rs", pos); + } + + public String getResultSetMethodObject(String resultSet, String pos) + { + switch (getMappedType()) + { + case M_ARRAY: return resultSet + ".getArray(" + pos + ")"; + case M_LONG : return "getLong(" + resultSet + ", "+pos+")"; + case M_BYTES : return resultSet + ".getBytes(" + pos + ")"; + case M_BLOB : return resultSet + ".getBlob("+pos+")"; + case M_BOOLEAN : return "getBoolean(" + resultSet + ", "+pos+")"; + case M_STRING : return resultSet + ".getString(" + pos + ")"; + case M_CLOB : return resultSet + ".getClob("+pos+")"; + case M_URL : return resultSet + ".getURL("+pos+")"; + case M_BIGDECIMAL : return resultSet + ".getBigDecimal(" + pos + ")"; + case M_DOUBLE : return "getDouble(" + resultSet + ", "+pos+")"; + case M_FLOAT : return "getFloat(" + resultSet + ", "+pos+")"; + case M_INTEGER : return "getInteger(" + resultSet + ", "+pos+")"; + + case M_OBJECT : return resultSet + ".getObject("+pos+")"; + case M_REF : return resultSet + ".getRef("+pos+")"; + case M_SQLDATE : return resultSet + ".getDate(" + pos + ")"; + case M_TIME :return resultSet + ".getTime(" + pos + ")"; + case M_TIMESTAMP :return resultSet + ".getTimestamp(" + pos + ")"; + case M_UTILDATE : + switch(getType()) { + case Types.TIME: return resultSet + ".getTime(" + pos + ")"; + case Types.TIMESTAMP: return resultSet + ".getTimestamp(" + pos + ")"; + case Types.DATE: return resultSet + ".getDate(" + pos + ")"; + } + default:tuoe(); + } + return null; + } + + + /** + * Maps the SQL type for the column to a "set" method to call on + * the PreparedStatement. + *
+ * This is used when generating Manager classes. There are some + * variations in how different databases may deal with this, so you + * might look at the OracleManagerWriter to see how you might have + * to override this method for your particular database. + * + * @param var Java code that represents how we'll get access to the + * value to set. You should be able to use this value + * verbatim. Check out the source to this method to + * see what we mean. + * @param pos The position to pass as the first argument of the set + * method. You will be able to use this verbatim too. + * @return The string to write into the generated Manager .java file. + */ + public String getPreparedStatementMethod(String var,int pos) + { + return getPreparedStatementMethod(var, Integer.toString(pos)); + } + + public String getPreparedStatementMethod(String var, String pos) + { + switch(getMappedType()) + { + case M_ARRAY: return "ps.setArray(" + pos + ", " + var + ");"; + case M_LONG: return "setLong(ps, "+pos+", "+var+");"; + case M_BYTES: return "ps.setBytes(" + pos + ", " + var + ");"; + case M_BLOB : return "ps.setBlob(" + pos + ", " + var + ");"; + case M_BOOLEAN : return "setBoolean(ps, "+pos+", "+var+");"; + case M_STRING:return "ps.setString(" + pos + ", " + var + ");"; + case M_CLOB : return "ps.setClob(" + pos + ", " + var + ");"; + case M_URL : return "ps.setURL(" + pos + ", " + var + ");"; + case M_BIGDECIMAL: return "ps.setBigDecimal(" + pos + ", " + var + ");"; + case M_DOUBLE: return "setDouble(ps, "+pos+", "+var+");"; + case M_INTEGER: return "setInteger(ps, "+pos+", "+var+");"; + case M_OBJECT : return "ps.setObject(" + pos + ", " + var + ");"; + case M_FLOAT: return "setFloat(ps, "+pos+", "+var+");"; + case M_SQLDATE: return "ps.setDate(" + pos + ", " + var + ");"; + case M_TIME: return "ps.setTime(" + pos + ", " + var + ");"; + case M_TIMESTAMP: return "ps.setTimestamp(" + pos + ", " + var + ");"; + case M_UTILDATE: + switch(getType()) { + case Types.TIMESTAMP: return "if (" + var + " == null) ps.setNull("+pos+", "+getJavaTypeAsTypeName()+"); else ps.setTimestamp(" + pos + ", new java.sql.Timestamp(" + var + ".getTime()));"; + case Types.DATE: return "if (" + var + " == null) ps.setNull("+pos+", "+getJavaTypeAsTypeName()+"); else ps.setDate(" + pos + ", new java.sql.Date(" + var + ".getTime()));"; + case Types.TIME: return "if (" + var + " == null) ps.setNull("+pos+", "+getJavaTypeAsTypeName()+"); else ps.setTime(" + pos + ", new java.sql.Time(" + var + ".getTime()));"; + default: return null; + } + case M_REF: return "ps.setRef(" + pos + ", " + var + ");"; + default: return "ps.setObject(" + pos + ", " + var + ");"; + } + } + + /** + * method to convert the given string into the internal java representation + */ + public String getStringConvertionMethod() + { + switch (getMappedType()) + { + case M_BIGDECIMAL: return "new java.math.BigDecimal"; + case M_BOOLEAN: return "new Boolean"; + case M_SQLDATE: return "new java.sql.Date"; + case M_DOUBLE: return "new Double"; + case M_FLOAT: return "new Float"; + case M_INTEGER: return "new Integer"; + case M_LONG: return "new Long"; + case M_STRING: return ""; + case M_TIME: + case M_TIMESTAMP: + case M_UTILDATE: + if (CodeWriter.dateClassName.equals("java.util.GregorianCalendar")) + return "GregorianDate"; + else + return "getDateFromString"; + case M_URL: + case M_OBJECT: + case M_REF: + case M_ARRAY: + case M_BYTES: + case M_CLOB: + default: + System.err.println("type unknown for " + getFullName()); + return ""; + } + } + + /* + * get the default widget name for the current column + */ + public String getDefaultWidget() + { + if (isForeignKey()) + return "SelectWidget"; + if (isString() && (getSize() > 200 || getSize() == -1)) + return "TextAreaWidget"; + + switch (getMappedType()) + { + case M_BOOLEAN: return "BooleanWidget"; + case M_TIME: + case M_TIMESTAMP: + case M_UTILDATE: + case M_SQLDATE: return "DateWidget"; + case M_BIGDECIMAL: + case M_DOUBLE: + case M_FLOAT: + case M_INTEGER: + case M_LONG: + case M_URL: + case M_OBJECT: + case M_REF: + case M_ARRAY: + case M_BYTES: + case M_CLOB: + case M_STRING: return "InputWidget"; + default: + System.err.println("type unknown for " + getFullName()); + return ""; + } + } + + /* + * is there an optimistic locking column ? + */ + static boolean isPresentLock(Column[] cols, String optimisticLockType, String optimisticLockColumn) { + boolean retVal = false; + if (optimisticLockType.equalsIgnoreCase("timestamp")) { + for(int i = 0; i < cols.length; i++) + { + if ( cols[i].getName().equalsIgnoreCase(optimisticLockColumn) && + (cols[i].getMappedType()==Column.M_LONG || cols[i].getMappedType()==Column.M_STRING) ) { + // + retVal = true; + break; + } + } + } + return retVal; + } + + public Table getTable() + { + return db.getTable(getTableName()); + } + + public void addForeignKey(Column col) + { + foreignKeys.add(col); + getTable().addForeignKey(this); + } + + public List getForeignKeys() + { + return foreignKeys; + } + + public void addImportedKey(Column col) + { + importedKeys.add(col); + getTable().addImportedKey(col); + } + + public List getImportedKeys() + { + return importedKeys; + } + + public int countImportedKeys() + { + return importedKeys.size(); + } + + public boolean isImportedKey() + { + if (countImportedKeys() > 0) + return true; + return false; + } + + public Column getForeignColumn() + { + return (Column)foreignKeys.get(0); + } + + public int countForeignKeys() + { + return foreignKeys.size(); + } + + public boolean isForeignKey() + { + if (countForeignKeys() > 0) + return true; + return false; + } + + public String getPropertyTag() + { + return (getTableName() + "." + getName()).toLowerCase(); + } + + public String getVarName() + { + return StringUtilities.convertName(getName(), true); + } + + public String getDefaultRules() + { + String rule = ""; + if (getNullable() == 0 && isPrimaryKey() == false) + rule = rule + " nullnotallowed"; + else + rule = rule + " nullallowed"; + if (getType() == Types.DATE || getType() == Types.TIMESTAMP) + rule = rule + " dateformat"; + return rule; + } + + /** + * is this column described to be in the given type ? + * check in sql2java.properties the table.[TABLENAME].in.[TYPE].exclude & table.[TABLENAME].in.[TYPE].include + */ + public boolean columnFor(String type) + { + String property = "table." + getTableName().toLowerCase() + ".in." + type.toLowerCase(); + String[] exclude = CodeWriter.getPropertyExploded(property + ".exclude"); + String[] include = CodeWriter.getPropertyExploded(property + ".include"); + if (exclude.length == 0 && include.length == 0) + return true; + if (Main.isInArray(include, getName())) + return true; + if (Main.isInArray(exclude, getName())) + return false; + if (include.length == 0) + return true; + return false; + } + +} diff --git a/src/main/java/net/sourceforge/sql2java/Database.java b/src/main/java/net/sourceforge/sql2java/Database.java new file mode 100755 index 0000000..cf19638 --- /dev/null +++ b/src/main/java/net/sourceforge/sql2java/Database.java @@ -0,0 +1,341 @@ +//$Id: Database.java,v 1.1 2005/10/12 18:44:24 framiere Exp $ + +package net.sourceforge.sql2java; + +import java.sql.*; +import java.util.*; +import java.io.*; +import java.util.Vector; +import java.util.Hashtable; + +public class Database +{ + private String tableTypes[]; + private Connection pConnection; + private DatabaseMetaData meta; + private Vector tables; + private Hashtable tableHash; + private String driver, url, username, password, catalog, schema, tablenamepattern; + private boolean retrieveRemarks = true; + + public void setOracleRetrieveRemarks(boolean retrieveRemarks) { this.retrieveRemarks = retrieveRemarks;} + public void setDriver(String driver) { this.driver = driver; } + public void setUrl(String url) { this.url = url; } + public void setUsername(String username) { this.username = username; } + public void setPassword(String password) { this.password = password; } + public void setCatalog(String catalog) { this.catalog = catalog; } + public void setTableNamePattern(String tablenamepattern) { this.tablenamepattern = tablenamepattern; } + public void setTableTypes(String[] tt) { this.tableTypes = tt; } + + public boolean getOracleRetrieveRemarks() { return this.retrieveRemarks; } + public String getDriver() { return driver; } + public String getUrl() { return url; } + public String getUsername() { return username; } + public String getPassword() { return password; } + public String getCatalog() { return catalog; } + public String getSchema() { return schema; } + public String getTableNamePattern() { return tablenamepattern; } + public String[] getTableTypes() { return tableTypes; } + + + public void setSchema(String schema) + { + if ("null".equalsIgnoreCase(schema)) + this.schema = null; + else + this.schema = schema; + } + + + /** + * Return an array of tables having foreign key pointing to the + * passed table. + */ + public Table[] getRelationTable(Table table) + { + Vector vector = new Vector(); + + for (int iIndex = 0; iIndex < tables.size(); iIndex ++) + { + Table tempTable = (Table)tables.get(iIndex); + + // skip itself + if (table.equals(tempTable)) + continue; + + // check only for relation table + if (tempTable.isRelationTable()) + { + if (tempTable.relationConnectsTo(table)) + { + if (!vector.contains(tempTable)) + vector.add(tempTable); + } + } + } + return (Table[])vector.toArray(new Table[0]); + } + + public void load() throws SQLException, ClassNotFoundException + { + // Connect to the database + Class.forName(driver); + + + System.out.println("Connecting to " + username + " on " + url + " ..."); + pConnection = DriverManager.getConnection(url, username, password); + System.out.println(" Connected."); +// if (pConnection instanceof oracle.jdbc.driver.OracleConnection) +// ((oracle.jdbc.driver.OracleConnection)pConnection).setRemarksReporting(getOracleRetrieveRemarks()); + + meta = pConnection.getMetaData(); + System.out.println(" Database server :" + meta.getDatabaseProductName() + "."); + tables = new Vector(); + tableHash = new Hashtable(); + + loadTables(); + loadColumns(); + loadPrimaryKeys(); + // loadImportedKeys(); + // loadManyToMany(); +// loadIndexes(); // experimental + } + + public Table[] getTables() + { + return (Table[])tables.toArray(new Table[0]); + } + + private void addTable(Table t) { + tables.addElement(t); + tableHash.put(t.getName(), t); + } + + public Table getTable(String name) { + return (Table)tableHash.get(name); + } + + /** + * Load all the tables for this schema. + */ + private void loadTables() throws SQLException + { + System.out.println("Loading table list according to pattern " + tablenamepattern + " ..."); + + // tablenamepattern is now a comma-separated list of patterns + java.util.StringTokenizer st = new java.util.StringTokenizer(tablenamepattern, ",; \t"); + while(st.hasMoreTokens()) { + String pattern = ((String)st.nextToken()).trim(); + ResultSet resultSet = meta.getTables(catalog, schema, pattern, tableTypes); + while(resultSet.next()) + { + Table table = new Table(); + table.setDatabase(this); + table.setCatalog(resultSet.getString("TABLE_CAT")); + table.setSchema(resultSet.getString("TABLE_SCHEM")); + table.setName(resultSet.getString("TABLE_NAME")); + table.setType(resultSet.getString("TABLE_TYPE")); + table.setRemarks(resultSet.getString("REMARKS")); + addTable(table); + System.out.println(" table " + table.getName() + " found"); + } + resultSet.close(); + } + } + + /** + * For each table, load all the columns. + */ + private void loadColumns() throws SQLException + { + Table tables[] = getTables(); + + System.out.println("Loading columns ..."); + boolean b = false; + for(int i = 0; i < tables.length; i++) + { + Table table = tables[i]; + ResultSet resultSet = meta.getColumns(catalog, schema, table.getName(), "%"); + Column c = null; + + while(resultSet.next()) + { + c = new Column(); + c.setDatabase(this); + c.setCatalog(resultSet.getString("TABLE_CAT")); + c.setSchema(resultSet.getString("TABLE_SCHEM")); + c.setTableName(resultSet.getString("TABLE_NAME")); + c.setName(resultSet.getString("COLUMN_NAME")); + c.setType(resultSet.getShort("DATA_TYPE")); + c.setSize(resultSet.getInt("COLUMN_SIZE")); + c.setDecimalDigits(resultSet.getInt("DECIMAL_DIGITS")); + c.setRadix(resultSet.getInt("NUM_PREC_RADIX")); + c.setNullable(resultSet.getInt("NULLABLE")); + c.setRemarks(resultSet.getString("REMARKS")); + c.setDefaultValue(resultSet.getString("COLUMN_DEF")); + c.setOrdinalPosition(resultSet.getInt("ORDINAL_POSITION")); + table.addColumn(c); + } + System.out.println(" " + table.getName() + " found " + table.countColumns() + " columns"); + + resultSet.close(); + } + } + + /** + * For each table, load the primary keys. + */ + private void loadPrimaryKeys() throws SQLException + { + System.out.println("Loading primary keys ..."); + Table tables[] = getTables(); + + for(int i = 0; i < tables.length; i++) + { + Table table = tables[i]; + ResultSet resultSet = meta.getPrimaryKeys(catalog, schema, table.getName()); + + while(resultSet.next()) + { + Column col = table.getColumn(resultSet.getString("COLUMN_NAME")); + table.addPrimaryKey(col); + System.out.println(" " + col.getFullName() + " found"); + } + + resultSet.close(); + } + } + + /** + * For each table, load the imported key. + *
+ * An imported key is the other's table column clone. Its + * ForeignKeyColName corresponds to the table's column name that + * points to the other's table. + */ + private void loadImportedKeys() throws SQLException + { + System.out.println("Loading imported keys ..."); + Table tables[] = getTables(); + + for(int i = 0; i < tables.length; i++) + { + Table table = tables[i]; + ResultSet resultSet = meta.getImportedKeys(catalog, schema, table.getName()); + while(resultSet.next()) + { + String tabName = resultSet.getString("FKTABLE_NAME"); + String colName = resultSet.getString("FKCOLUMN_NAME"); + + String foreignTabName= resultSet.getString("PKTABLE_NAME"); + String foreignColName= resultSet.getString("PKCOLUMN_NAME"); + + Column col = getTable(tabName).getColumn(colName); + Column foreignCol = getTable(foreignTabName).getColumn(foreignColName); + + col.addForeignKey(foreignCol); + foreignCol.addImportedKey(col); + //getTable(foreignTabName).addImportedKey(col); + + System.out.println(" " + col.getFullName() + " -> " + foreignCol.getFullName() + " found "); + } + + resultSet.close(); + } + } + + // + // could avoid db call. + // In each current table an entry is: + // other table column (that points to current table) | current pk column + // [other table has nb col. == pk length] + private void loadManyToMany() throws SQLException + { + System.out.println("Loading many to many relationships..."); + Table tables[] = getTables(); + + for(int i = 0; i < tables.length; i++) + { + Table table = tables[i]; + +// if(table.getColumns().length == table.getPrimaryKeys().length) + { + ResultSet resultSet = meta.getImportedKeys(catalog, schema, table.getName()); + + while(resultSet.next()) + { + String tabName = resultSet.getString("PKTABLE_NAME"); + String colName = resultSet.getString("PKCOLUMN_NAME"); + System.out.println(" many to many " + tabName + " " + colName); + + Table pkTable = getTable(tabName); + Column fkCol = table.getColumn(resultSet.getString("FKCOLUMN_NAME")); + + if(pkTable != null) + { + Column pkCol = pkTable.getColumn(colName); + + if(pkCol != null && fkCol != null) + { + pkTable.addManyToManyKey(fkCol, pkCol); + } + } + } + + resultSet.close(); + } + } + } + + /** + * For each table, load the indexes. + */ + private void loadIndexes() throws SQLException + { + System.out.println("Loading indexes ..."); + Table tables[] = getTables(); + + for(int i = 0; i < tables.length; i++) + { + Table table = tables[i]; + ResultSet resultSet = meta.getIndexInfo(catalog, + schema, + table.getName(), + true, + true); + while(resultSet.next()) + { + String colName = resultSet.getString("COLUMN_NAME"); + String indName = resultSet.getString("INDEX_NAME"); + + if (colName != null && indName != null) { + Column col = table.getColumn(colName); + if (!col.isPrimaryKey()) + System.out.println(" Found interesting index " + indName + " on " + + colName + " for table " + table.getName()); + } + } + + resultSet.close(); + } + } + + public String[] getAllPackages() + { + Vector vector = new Vector(); + for (int iIndex = 0; iIndex < tables.size(); iIndex ++) + { + Table table = (Table)tables.get(iIndex); + String packages[] = table.getLinkedPackages(); + for (int i = 0; i < packages.length; i++) + { + if (vector.contains(packages[i]) == false) + { + vector.add(packages[i]); + } + } + } + return (String[])vector.toArray(new String[0]); + } + +} diff --git a/src/main/java/net/sourceforge/sql2java/Main.java b/src/main/java/net/sourceforge/sql2java/Main.java new file mode 100755 index 0000000..576ae3d --- /dev/null +++ b/src/main/java/net/sourceforge/sql2java/Main.java @@ -0,0 +1,115 @@ +//$Id: Main.java,v 1.1 2005/10/12 18:44:24 framiere Exp $ + +package net.sourceforge.sql2java; + +import java.util.*; +import java.io.*; +import java.sql.SQLException; + +public class Main { + + /** + * properties given in the command line + */ + private static Properties prop; + + /** + * main entry point + */ + public static void main(String argv[]) + { + main(argv, null); + } + + /** + * main entry point + */ + public static void main(String argv[], Map overideFileProperties) + { + // Check for required argument + if(argv == null || argv.length < 1) { + System.err.println("Usage: java com.netkernel.sql2java.Main "); + System.exit(1); + } + + //properties already here ? + prop = new Properties(); + try + { + prop.load(new FileInputStream(argv[0])); + Database db = new Database(); + db.setDriver(getProperty("jdbc.driver")); + db.setUrl(getProperty("jdbc.url")); + db.setUsername(getProperty("jdbc.username")); + db.setPassword(getProperty("jdbc.password")); + db.setCatalog(getProperty("jdbc.catalog")); + db.setSchema(getProperty("jdbc.schema")); + db.setTableNamePattern(getProperty("jdbc.tablenamepattern")); + + + if (overideFileProperties != null) + prop.putAll(overideFileProperties); + + if ("false".equalsIgnoreCase(getProperty("jdbc.oracle.retrieve.remarks"))) + db.setOracleRetrieveRemarks(false); + else + db.setOracleRetrieveRemarks(true); + + String tt = getProperty("jdbc.tabletypes", "TABLE"); + StringTokenizer st = new StringTokenizer(tt, ",; \t"); + ArrayList al = new ArrayList(); + + while(st.hasMoreTokens()) { + al.add(((String)st.nextToken()).trim()); + } + + db.setTableTypes((String[])al.toArray(new String[al.size()])); + + db.load(); + + CodeWriter writer = new CodeWriter(db, prop); + // override destdir if given + if (argv.length > 1) + writer.setDestinationFolder(argv[1]); + writer.process(); + } + catch(Exception e) + { + e.printStackTrace(); + System.exit(1); + } + } + + public static String getProperty(String key) + { + String s = prop.getProperty(key); + return s!=null?s.trim():s; + } + + /** + * helper method with default values + */ + public static String getProperty(String key, String default_val) + { + String s = getProperty(key); + if (s == null) + return default_val; + return s; + } + + /** + * is the given code in the string array ? + */ + public static boolean isInArray(String[] ar, String code) + { + if (ar == null) + return false; + for (int i = 0; i < ar.length; i ++) + { + if (code.equalsIgnoreCase(ar[i])) + return true; + } + return false; + } + +} diff --git a/src/main/java/net/sourceforge/sql2java/StringUtilities.java b/src/main/java/net/sourceforge/sql2java/StringUtilities.java new file mode 100755 index 0000000..5f1f5a2 --- /dev/null +++ b/src/main/java/net/sourceforge/sql2java/StringUtilities.java @@ -0,0 +1,527 @@ +//$Id: StringUtilities.java,v 1.3 2005/10/17 22:04:10 framiere Exp $ + +package net.sourceforge.sql2java; + +import java.io.*; + +/** + * @author Kelvin Nishikawa + * + * This utility class handles various SQL -> Java String conversions for code in various templates. + * Use sharedInstance() to get the singleton instance. + * + * Most of these methods were excised to here from the CodeWriter class for good housekeeping. + * + */ +public final class StringUtilities { + static private StringUtilities singleton = new StringUtilities(); + + // TODO: convert into velocity macros + static public final String PREFIX = ""; + static public final String BASE_SUFFIX = ""; + static public final String MANAGER_SUFFIX = "Manager"; + //static public final String BEAN_SUFFIX = "Bean"; + static public final String BEAN_SUFFIX = ""; + static public final String RELATIONNAL_BEAN_SUFFIX = "Relationnal_Bean"; + static public final String HIBERNATE_MANAGER_SUFFIX = "Hibernate_Manager"; + static public final String ITERATOR_SUFFIX = "Iterator"; + static public final String FACTORY_SUFFIX = "Factory"; + static public final String COMPARATOR_SUFFIX = "Comparator"; + static public final String HTTP_FACTORY_SUFFIX = "Http_Factory"; + static public final String LISTENER_SUFFIX = "Listener"; + static public final String RENDERER_SUFFIX = "Renderer"; + static public final String EXCEPTION_SUFFIX = "Exception"; + static public final String WIDGETFACTORY_SUFFIX = "Widget_Factory"; + static public final String WIDGET_SUFFIX = "Widget"; + + private StringUtilities () { } + + /** This is the default method for obtaining a StringUtilities instance. + * @return The shared instance + */ + static public synchronized StringUtilities getInstance() { + return singleton; + } + + public String getPackageAsPath(String pkg){ + if (pkg == null) + return ""; + return pkg.replace('.', '/'); + } + + public String getDefaultRules(Column col){ + return col.getDefaultRules(); + } + + public String getPropertyTag(Column col){ + return col.getPropertyTag(); + } + + // TODO: convert into velocity macros + public String convertClass(String table, String type) + { + String suffix = ""; + String postfix = ""; + if ("".equalsIgnoreCase(PREFIX) == false) + suffix = suffix + "_"; + if ("".equalsIgnoreCase(type) == false) + postfix = "_" + type; + return convertName(suffix + table + postfix); + } + + public String getCoreClass(Table table) + { + return convertClass(table.getName(), BASE_SUFFIX); + } + + public String getCoreClass(String table) + { + return convertClass(table, BASE_SUFFIX); + } + + public String getBeanClass(Table table) + { + return convertClass(table.getName(), BEAN_SUFFIX); + } + + public String getBeanClass(String table) + { + return convertClass(table, BEAN_SUFFIX); + } + + public String getRelationnalBeanClass(Table table) + { + return convertClass(table.getName(), RELATIONNAL_BEAN_SUFFIX); + } + + public String getRelationnalBeanClass(String table) + { + return convertClass(table, RELATIONNAL_BEAN_SUFFIX); + } + + public String getFactoryClass(Table table) + { + return convertClass(table.getName(), FACTORY_SUFFIX); + } + + public String getFactoryClass(String table) + { + return convertClass(table, FACTORY_SUFFIX); + } + + public String getHttpFactoryClass(Table table) + { + return convertClass(table.getName(), HTTP_FACTORY_SUFFIX); + } + + public String getHttpFactoryClass(String table) + { + return convertClass(table, HTTP_FACTORY_SUFFIX); + } + + public String getListenerClass(Table table) + { + return convertClass(table.getName(), LISTENER_SUFFIX); + } + + public String getListenerClass(String table) + { + return convertClass(table, LISTENER_SUFFIX); + } + + public String getRendererClass(Table table) + { + return convertClass(table.getName(), RENDERER_SUFFIX); + } + + public String getRendererClass(String table) + { + return convertClass(table, RENDERER_SUFFIX); + } + + public String getWidgetFactoryClass(Table table) + { + return convertClass(table.getName(), WIDGETFACTORY_SUFFIX); + } + + public String getWidgetFactoryClass(String table) + { + return convertClass(table, WIDGETFACTORY_SUFFIX); + } + + public String getExceptionClass(Table table) + { + return convertClass(table.getName(), EXCEPTION_SUFFIX); + } + + public String getExceptionClass(String table) + { + return convertClass(table, EXCEPTION_SUFFIX); + } + + public String getWidgetClass(Table table) + { + return convertClass(table.getName(), WIDGET_SUFFIX); + } + + public String getWidgetClass(String table) + { + return convertClass(table, WIDGET_SUFFIX); + } + + public String getIteratorClass(Table table) + { + return convertClass(table.getName(), ITERATOR_SUFFIX); + } + + public String getIteratorClass(String table) + { + return convertClass(table, ITERATOR_SUFFIX); + } + + public String getManagerClass(Table table) + { + return convertClass(table.getName(), MANAGER_SUFFIX); + } + + public String getManagerClass(String table) + { + return convertClass(table, MANAGER_SUFFIX); + } + + public String getHibernateManagerClass(Table table) + { + return convertClass(table.getName(), HIBERNATE_MANAGER_SUFFIX); + } + + public String getHibernateManagerClass(String table) + { + return convertClass(table, HIBERNATE_MANAGER_SUFFIX); + } + + public String getComparatorClass(Table table) + { + return convertClass(table.getName(), COMPARATOR_SUFFIX); + } + + public String getComparatorClass(String table) + { + return convertClass(table, COMPARATOR_SUFFIX); + } + + public String getStringConvertionMethod(Column col){ + return col.getStringConvertionMethod(); + } + + public String getGetMethod(Column col) { + return getGetMethod(col.getName()); + } + + public String getSetMethod(Column col) { + return getSetMethod(col.getName()); + } + + public String getModifiedMethod(Column col) { + return getModifiedMethod(col.getName()); + } + + public String getInitializedMethod(Column col) { + return getInitializedMethod(col.getName()); + } + + public String getWidgetMethod(Column col) { + return getWidgetMethod(col.getName()); + } + + + public String getGetMethod(String col) { + return convertName("get_" + escape(col), true); + } + + public String getSetMethod(String col) { + return convertName("set_" + escape(col), true); + } + + public String getModifiedMethod(String col) { + return convertName("is_" + escape(col) + "_modified", true); + } + + public String getInitializedMethod(String col) { + return convertName("is_" + escape(col) + "_initialized", true); + } + + public String getWidgetMethod(String col) { + return convertName("get_" + escape(col) + "_widget", true); + } + + public String getVarName(Column c) { + return convertName(escape(c), true); + } + + public String getVarName(String c) { + return convertName(escape(c), true); + } + + public String getModifiedVarName(Column c) { + return getVarName(c) + "_is_modified"; // already escaped + } + + public String getInitializedVarName(Column c) { + return getVarName(c) + "_is_initialized";// already escaped + } + + // foreign keys + public String getForeignKeyVarName(Column c) { + return convertName(escape(c) + "_object", true); + } + + public String getForeignKeyModifiedVarName(Column c) { + return getVarName(c) + "_object_is_modified"; // already escaped + } + + public String getForeignKeyInitializedVarName(Column c) { + return getVarName(c) + "_object_is_initialized";// already escaped + } + + public String getForeignKeyInitializedMethod(Column col) { + return convertName("is_" + escape(col) + "_object_initialized", true); + } + + public String getForeignKeyGetMethod(Column col) { + return convertName("get_" + escape(col) + "_object", true); + } + + public String getForeignKeySetMethod(Column col) { + return convertName("set_" + escape(col) + "_object", true); + } + + public String getForeignKeyModifiedMethod(Column col) { + return convertName("is_" + escape(col) + "_object_modified", true); + } + + public String getForeignKeyVarName(String col) { + return convertName(escape(col) + "_object", true); + } + + public String getForeignKeyModifiedVarName(String c) { + return getVarName(c) + "_object_is_modified"; // already escaped + } + + public String getForeignKeyInitializedVarName(String c) { + return getVarName(c) + "_object_is_initialized";// already escaped + } + + public String getForeignKeyInitializedMethod(String col) { + return convertName("is_" + escape(col) + "_object_initialized", true); + } + + public String getForeignKeyGetMethod(String col) { + return convertName("get_" + escape(col) + "_object", true); + } + + public String getForeignKeySetMethod(String col) { + return convertName("set_" + escape(col) + "_object", true); + } + + public String getForeignKeyModifiedMethod(String col) { + return convertName("is_" + escape(col) + "_object_modified", true); + } + + // imported keys + public String getImportedKeyVarName(Column c) { + return convertName(escape(c) + "_collection", true); + } + + public String getImportedKeyModifiedVarName(Column c) { + return getVarName(c) + "_collection_is_modified"; // already escaped + } + + public String getImportedKeyInitializedVarName(Column c) { + return getVarName(c) + "_collection_is_initialized";// already escaped + } + + public String getImportedKeyInitializedMethod(Column col) { + return convertName("is_" + escape(col) + "_collection_initialized", true); + } + + public String getImportedKeyGetMethod(Column col) { + return convertName("get_" + escape(col) + "_collection", true); + } + + public String getImportedKeyAddMethod(Column col) { + return convertName("add_" + escape(col) + "", true); + } + + public String getImportedKeySetMethod(Column col) { + return convertName("set_" + escape(col) + "_collection", true); + } + + public String getImportedKeyModifiedMethod(Column col) { + return convertName("is_" + escape(col) + "_collection_modified", true); + } + + public String getImportedKeyVarName(String col) { + return convertName(escape(col) + "_collection", true); + } + + public String getImportedKeyModifiedVarName(String c) { + return getVarName(c) + "_collection_is_modified"; // already escaped + } + + public String getImportedKeyInitializedVarName(String c) { + return getVarName(c) + "_collection_is_initialized";// already escaped + } + + public String getImportedKeyInitializedMethod(String col) { + return convertName("is_" + escape(col) + "_collection_initialized", true); + } + + public String getImportedKeyGetMethod(String col) { + return convertName("get_" + escape(col) + "_collection", true); + } + + public String getImportedKeyAddMethod(String col) { + return convertName("add_" + escape(col) + "", true); + } + + public String getImportedKeySetMethod(String col) { + return convertName("set_" + escape(col) + "_collection", true); + } + + public String getImportedKeyModifiedMethod(String col) { + return convertName("is_" + escape(col) + "_collection_modified", true); + } + + + public String getJavaPrimaryType( Column c ) { + try { + return c.getJavaPrimaryType(); + } catch ( Exception e ) { + return null; + } + } + + public String convertName(String name) { + return convertName(name, false); + } + + public String convertName(Column col) { + return convertName(col.getName(), false); + } + + public String convertName(Table table) { + return convertName(table.getName(), false); + } + + /** + * Converts name into a more Java-ish style name. + * @author netkernel + *
+ * Basically it looks for underscores, removes them, and makes the + * letter after the underscore a capital letter. If wimpyCaps is true, + * then the first letter of the name will be lowercase, otherwise it + * will be uppercase. Here are some examples: + *

+ * member_profile becomes MemberProfile + *
+ * firstname           becomes  Firstname + */ + public static String convertName(String name, boolean wimpyCaps) { + StringBuffer buffer = new StringBuffer(name.length()); + //char list[] = name.toLowerCase().toCharArray(); + char list[] = name.toCharArray(); + for(int i = 0; i < list.length; i++) { + if(i == 0 && !wimpyCaps) { + buffer.append(Character.toUpperCase(list[i])); + } else if(list[i] == '_' && (i+1) < list.length && i != 0) { + buffer.append(Character.toUpperCase(list[++i])); + } else buffer.append(list[i]); + } + return buffer.toString(); + } +// ORIGINAL CONVERT STRING +// public static String convertName(String name, boolean wimpyCaps) { +// StringBuffer buffer = new StringBuffer(name.length()); +// char list[] = name.toLowerCase().toCharArray(); +// for(int i = 0; i < list.length; i++) { +// if(i == 0 && !wimpyCaps) { +// buffer.append(Character.toUpperCase(list[i])); +// } else if(list[i] == '_' && (i+1) < list.length && i != 0) { +// buffer.append(Character.toUpperCase(list[++i])); +// } else buffer.append(list[i]); +// } +// return buffer.toString(); +// } + + private String escape(String s) { + return isReserved(s) ? ("my_"+s) : s; + } + + private String escape(Column s) { + return isReserved(s.getName()) ? ("my_"+s.getName()) : s.getName(); + } + + boolean isReserved(String s) { + for(int i=0; i 1; + } + + /** + * Tells whether if one of this table's columns (imported key) + * points to one of the otherTable's pk. + */ + public boolean relationConnectsTo(Table otherTable) + { + if (this.equals(otherTable)) + { + return false; + } + + for (int i = 0; i < foreignKeys.size(); i++) + { + Column c = (Column) importedKeys.get(i); + if (c.getTableName().equals(otherTable.getName())) + { + return true; + } + } + return false; + } + + /** + * Return, beside the passed table, the tables this table points to. + */ + public Table[] linkedTables(Database pDatabase, Table pTable) + { + Vector vector = new Vector(); + + for (int iIndex = 0; iIndex < importedKeys.size(); iIndex++) + { + Column pColumn = (Column) importedKeys.get(iIndex); + if (pColumn.getTableName().equals(pTable.getName()) == false) + { + Table pTableToAdd = pDatabase.getTable(pColumn.getTableName()); + if (vector.contains(pTableToAdd) == false) + vector.add(pTableToAdd); + } + } + return (Table[])vector.toArray(new Table[0]); + } + + /** + * Return the imported key pointing to the passed table. + */ + public Column getForeignKeyFor(Table pTable) + { + Vector vector = new Vector(); + for (int iIndex = 0; iIndex < importedKeys.size(); iIndex++) + { + Column pColumn = (Column) importedKeys.get(iIndex); + if (pColumn.getTableName().equals(pTable.getName())) + return pColumn; + } + return null; + } + + public void setDatabase(Database db) + { + this.db = db; + } + public void setCatalog(String catalog) + { + this.catalog = catalog; + } + public void setSchema(String schema) + { + this.schema = schema; + } + public void setName(String name) + { + this.name = name; + } + public void setType(String type) + { + this.type = type; + } + public void setRemarks(String remarks) + { + if (remarks!=null) { + this.remarks = remarks.replaceAll("/\\*", "SLASH*").replaceAll("\\*/", "*SLASH"); + } +// else setRemarks("No remarks in this table /* escape me */ /** me too ****/ / * not me * /"); + } + + public String getCatalog() + { + return catalog; + } + public String getSchema() + { + return schema; + } + public String getName() + { + return name; + } + public String getType() + { + return type; + } + public String getRemarks() + { + return remarks==null?"":remarks; + } + + public Column[] getColumns() + { + return (Column[])cols.toArray(new Column[0]); + } + + public Column getColumn(String name) + { + return (Column) colHash.get(name.toLowerCase()); + } + + public void addColumn(Column column) + { + colHash.put(column.getName().toLowerCase(), column); + cols.addElement(column); + } + + public void removeColumn(Column column) + { + cols.removeElement(column); + colHash.remove(column.getName().toLowerCase()); + } + + public Column[] getPrimaryKeys() + { + return (Column[])priKey.toArray(new Column[0]); + } + + public void addPrimaryKey(Column column) + { + priKey.addElement(column); + column.isPrimaryKey(true); + } + + public Column[] getImportedKeys() + { + return (Column[])importedKeys.toArray(new Column[0]); + } + + public void addImportedKey(Column column) + { + if (importedKeys.contains(column) == false) + importedKeys.addElement(column); + } + + /** + * Returns a 2-D array of the keys in this table that form a many + * to many relationship. + *
+ * The size of the first dimension is based on the number of + * unique tables that are being managed. The second dimension + * is always 2 elements. The first element is the column in the + * relationship table itself. The second column is the primary + * key column in the target table. + */ + public Column[][] getManyToManyKeys() + { + + // // it matters only if we have 2 entries. + // if (manyToManyHash.size()<=1) { + // return new Column[0][0]; + // } + + Column list[][] = new Column[manyToManyHash.size()][2]; + int i = 0; + for (Enumeration e = manyToManyHash.keys(); e.hasMoreElements(); i++) + { + Column fk = (Column) e.nextElement(); + Column pk = (Column) manyToManyHash.get(fk); + list[i][0] = fk; + list[i][1] = pk; + } + return list; + } + + public void addManyToManyKey(Column fk, Column pk) + { + manyToManyHash.put(fk, pk); + } + + public int countColumns() + { + return cols.size(); + } + + public int countPrimaryKeys() + { + return priKey.size(); + } + + public boolean hasPrimaryKey() + { + return countPrimaryKeys() > 0; + } + + public int countImportedKeys() + { + return importedKeys.size(); + } + + public boolean hasImportedKeys() + { + return countImportedKeys() > 0; + } + + public int countForeignKeys() + { + return foreignKeys.size(); + } + + public boolean hasForeignKeys() + { + return countForeignKeys() > 0; + } + + public void addForeignKey(Column col) + { + if (foreignKeys.contains(col) == false) + foreignKeys.add(col); + } + + public Column[] getForeignKeys() + { + return (Column[])foreignKeys.toArray(new Column[0]); + } + + public boolean isForeignKey(Column col) + { + return foreignKeys.contains(col); + } + + public Table[] getLinkedTables() + { + Vector vector = new Vector(); + + for (int iIndex = 0; iIndex < importedKeys.size(); iIndex++) + { + Column column = (Column) importedKeys.get(iIndex); + if (column.getTableName().equals(getName()) == false) + { + Table pTableToAdd = column.getTable(); + if (vector.contains(pTableToAdd) == false) + vector.add(pTableToAdd); + } + } + + for (int iIndex = 0; iIndex < foreignKeys.size(); iIndex++) + { + Column column = (Column) foreignKeys.get(iIndex); + column = column.getForeignColumn(); + if (column.getTableName().equals(getName()) == false) + { + Table pTableToAdd = column.getTable(); + if (vector.contains(pTableToAdd) == false) + vector.add(pTableToAdd); + } + } + return (Table[])vector.toArray(new Table[0]); + } + + private Table[] getImportedTablesFromVector(Vector keys) + { + Vector vector = new Vector(); + for (int iIndex = 0; iIndex < keys.size(); iIndex++) + { + Column column = (Column) keys.get(iIndex); + if (column.getTableName().equals(getName()) == false) + { + Table pTableToAdd = column.getTable(); + if (vector.contains(pTableToAdd) == false) + vector.add(pTableToAdd); + } + } + return (Table[])vector.toArray(new Table[0]); + } + + public Table[] getImportedTables() + { + return getImportedTablesFromVector(importedKeys); + } + + public Table[] getForeignTables() + { + return getImportedTablesFromVector(foreignKeys); + } + + public String[] getLinkedPackages() + { + Vector vector = new Vector(); + Table[] linkedTables = getLinkedTables(); + for (int iIndex = 0; iIndex < linkedTables.length; iIndex++) + { + if (vector.contains(linkedTables[iIndex].getPackage()) == false) + vector.add(linkedTables[iIndex].getPackage()); + } + return (String[])vector.toArray(new String[0]); + } + + public String getPackage() + { + String basePackage = CodeWriter.getProperty("mgrwriter.package"); + // iterate in the subpackage.X.names + // starting at 1 + int iterating = 1; + while(true) + { + String tablesProperty = "subpackage." + iterating + ".tables"; + String packageNameProperty = "subpackage." + iterating + ".name"; + String tables[] = CodeWriter.getPropertyExploded(tablesProperty); + for (int i = 0; i < tables.length; i ++) + { + if (getName().equalsIgnoreCase(tables[i])) + { + String packageName = CodeWriter.getProperty(packageNameProperty); + if (packageName == null) + return basePackage; + return basePackage + "." + packageName; + } + } + iterating ++; + + // no tables found ? + // ok stop iterating + if (tables.length == 0) + break; + } + return basePackage; + } + + public String getPackagePath() + { + return getPackage().replace('.', '/'); + } + + public Column[] getColumnsFor(String type) + { + Vector vector = new Vector(); + for (int i = 0; i < cols.size(); i++) + { + Column c = (Column)cols.get(i); + if (c.columnFor(type)) + vector.add(c); + } + return (Column[])vector.toArray(new Column[0]); + } + +} diff --git a/src/main/java/net/sourceforge/sql2java/UserCodeParser.java b/src/main/java/net/sourceforge/sql2java/UserCodeParser.java new file mode 100755 index 0000000..d376c3d --- /dev/null +++ b/src/main/java/net/sourceforge/sql2java/UserCodeParser.java @@ -0,0 +1,172 @@ +//$Id: UserCodeParser.java,v 1.1 2005/10/12 18:44:24 framiere Exp $ + +package net.sourceforge.sql2java; + +import java.io.*; +import java.util.*; + +/** + * Parses an existing source file for special sql2code comment blocks. + *
+ * Stores the source code that it finds in between those blocks in a + * hashtable. This allows CodeWriter classes to rewrite existing files + * while preserving code written by the user. + * + * @author James Cooper + * @version $Id: UserCodeParser.java,v 1.1 2005/10/12 18:44:24 framiere Exp $ + */ +public class UserCodeParser { + + private static final String START = "// "; + private static final String BLOCK_BEGIN = "+ "; + private static final String BLOCK_END = "- "; + + private String LINE_SEP = System.getProperty("line.separator"); + private Hashtable codeHash; + private String filename; + private boolean isNew; + + /** + * Constructs a new parser, and tells the parser to try to load the + * given filename. + *
+ * If the file does not exist, the parser will simply initialize a + * new hashtable internally, and the get methods on the parser will + * return new comment blocks (with nothing in between them). + * + * @param filename Full path to the existing file to parse. + * @throws Exception if the existing file exists, but cannot be read, + * or if there is an error while reading the file + */ + public UserCodeParser(String filename) throws Exception { + parse(filename); + } + + /** + * Returns the filename associated with this parser. + */ + public String getFilename() { return filename; } + + /** + * Returns true if the file to parse did not exist. + */ + public boolean isNew() { return isNew; } + + /** + * Parses the file passed in. + */ + public void parse(String filename) throws Exception { + codeHash = new Hashtable(); + boolean inBlock = false; + String blockName = null; + StringBuffer code = new StringBuffer(); + isNew = true; + + File file = new File(filename); + if(file.exists()) { + isNew = false; + BufferedReader reader = new BufferedReader(new FileReader(file)); + String line = reader.readLine(); + while(line != null) { + if(inBlock) code.append(line).append(LINE_SEP); + + if(line.indexOf(START) != -1) { + if(inBlock) { + if(line.equals(START + blockName + BLOCK_END)) { + + // Done parsing block. Store it + codeHash.put(blockName, code.toString()); + inBlock = false; + } + } + else { + blockName = parseName(line); + if(!blockName.equals("")) { + inBlock = true; + code.setLength(0); + code.append(line).append(LINE_SEP); + } + } + } + + line = reader.readLine(); + } + reader.close(); + } + } + + private String parseName(String line) { + int startPos = line.indexOf(START); + if(startPos == -1) return ""; + startPos += START.length(); + + if(startPos >= (line.length() + 1)) return ""; + + int endPos = line.indexOf(BLOCK_BEGIN, startPos); + if(endPos == -1) return ""; + else { + String name = line.substring(startPos, endPos); + return name; + } + } + + /** + * Returns true if there is a block with the given name in the + * existing file that was parsed, otherwise returns false. + * + * @param name Name of the code block to check for. + */ + public boolean hasBlock(String name) { + return codeHash.get(name) != null; + } + + /** + * Returns the comment+code block associated with this name. + *
+ * If the name is not found in the parsed file, this returns a new + * comment block with no code inside it. + * + * @param name Name of the code block to return. + */ + public String getBlock(String name) { + String code = null; + if (name != null) code = (String)codeHash.get(name); + if(code == null) { + code = generateNewBlock(name); + codeHash.put(name, code); + } + return code; + } + + /** + * Returns an array of the block names parsed in the existing file. + *
+ * If the file did not exist, or if there are no blocks in the file, + * a zero length array is returned. + */ + public String[] getBlockNames() { + String list[] = new String[codeHash.size()]; + int i = 0; + for(Enumeration e = codeHash.keys(); e.hasMoreElements(); ) { + list[i++] = (String)e.nextElement(); + } + + return list; + } + + /** + * Generates a new code block with this name. + */ + private String generateNewBlock(String name) { + StringBuffer str = new StringBuffer(512); + str.append(START); + str.append(name); + str.append(BLOCK_BEGIN); + str.append(LINE_SEP).append(LINE_SEP); + str.append(START); + str.append(name); + str.append(BLOCK_END); + + return str.toString(); + } +} diff --git a/src/main/java/net/sourceforge/sql2java/ant/GenerationTask.java b/src/main/java/net/sourceforge/sql2java/ant/GenerationTask.java new file mode 100644 index 0000000..50c636e --- /dev/null +++ b/src/main/java/net/sourceforge/sql2java/ant/GenerationTask.java @@ -0,0 +1,24 @@ +//$Id: GenerationTask.java,v 1.1 2005/10/12 18:44:24 framiere Exp $ + +package net.sourceforge.sql2java.ant; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Task; +import net.sourceforge.sql2java.*; + +public class GenerationTask extends Task { + private String propertyFile; + + // The method executing the task + public void execute() throws BuildException + { + System.out.println("GenerationTask: " + propertyFile); + String args[] = new String[]{propertyFile}; + Main.main(args); + } + + // The setter for the "propertyFile" attribute + public void setPropertyFile(String msg) { + this.propertyFile = msg; + } +} \ No newline at end of file diff --git a/src/main/java/net/sourceforge/sql2java/ant/SchemaCheckTask.java b/src/main/java/net/sourceforge/sql2java/ant/SchemaCheckTask.java new file mode 100644 index 0000000..e8eb371 --- /dev/null +++ b/src/main/java/net/sourceforge/sql2java/ant/SchemaCheckTask.java @@ -0,0 +1,29 @@ +//$Id: SchemaCheckTask.java,v 1.1 2005/10/12 18:44:24 framiere Exp $ + +package net.sourceforge.sql2java.ant; + +import java.util.*; + +import net.sourceforge.sql2java.*; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Task; + +public class SchemaCheckTask extends Task { + private String propertyFile; + + // The method executing the task + public void execute() throws BuildException + { + System.out.println("SchemaCheckTask: " + propertyFile); + String args[] = new String[] {propertyFile}; + Map map = new HashMap(); + map.put("check.only.database", "true"); + Main.main(args, map); + } + + // The setter for the "propertyFile" attribute + public void setPropertyFile(String msg) { + this.propertyFile = msg; + } +} \ No newline at end of file diff --git a/src/main/java/net/sourceforge/sql2java/ant/TableGenerationTask.java b/src/main/java/net/sourceforge/sql2java/ant/TableGenerationTask.java new file mode 100644 index 0000000..0fd2c6d --- /dev/null +++ b/src/main/java/net/sourceforge/sql2java/ant/TableGenerationTask.java @@ -0,0 +1,35 @@ +//$Id: TableGenerationTask.java,v 1.1 2005/10/12 18:44:24 framiere Exp $ + +package net.sourceforge.sql2java.ant; + +import java.util.*; + +import net.sourceforge.sql2java.*; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Task; + +public class TableGenerationTask extends Task { + private String propertyFile; + private String tables; + + // The method executing the task + public void execute() throws BuildException + { + System.out.println("TableGenerationTask: " + propertyFile); + String args[] = new String[]{propertyFile}; + Map map = new HashMap(); + map.put("mgrwriter.include", tables); + Main.main(args, map); + } + + // The setter for the "propertyFile" attribute + public void setPropertyFile(String msg) { + this.propertyFile = msg; + } + + // The setter for the "table" attribute + public void setTables(String msg) { + this.tables = msg; + } +} \ No newline at end of file diff --git a/src/main/java/net/sourceforge/sql2java/ant/UtilsGenerationTask.java b/src/main/java/net/sourceforge/sql2java/ant/UtilsGenerationTask.java new file mode 100644 index 0000000..06516c2 --- /dev/null +++ b/src/main/java/net/sourceforge/sql2java/ant/UtilsGenerationTask.java @@ -0,0 +1,30 @@ +//$Id: UtilsGenerationTask.java,v 1.1 2005/10/12 18:44:24 framiere Exp $ + +package net.sourceforge.sql2java.ant; + +import java.util.*; + +import net.sourceforge.sql2java.*; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Task; + +public class UtilsGenerationTask extends Task { + private String propertyFile; + + // The method executing the task + public void execute() throws BuildException + { + System.out.println("UtilsGenerationTask: " + propertyFile); + String args[] = new String[] {propertyFile}; + Map map = new HashMap(); + map.put("check.database", "false"); + map.put("write.only.per.schema.templates", "true"); + Main.main(args, map); + } + + // The setter for the "propertyFile" attribute + public void setPropertyFile(String msg) { + this.propertyFile = msg; + } +} \ No newline at end of file diff --git a/src/main/java/net/sourceforge/sql2java/maven/Sql2JavaMojo.java b/src/main/java/net/sourceforge/sql2java/maven/Sql2JavaMojo.java new file mode 100644 index 0000000..4320598 --- /dev/null +++ b/src/main/java/net/sourceforge/sql2java/maven/Sql2JavaMojo.java @@ -0,0 +1,64 @@ +package net.sourceforge.sql2java.maven; + +import org.apache.maven.plugin.AbstractMojo; +import org.apache.maven.plugin.MojoExecutionException; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; + +/** + * Goal which touches a timestamp file. + * + * @goal touch + * + * @phase process-sources + */ +public class Sql2JavaMojo extends AbstractMojo +{ + /** + * Location of the file. + * @parameter expression="${project.build.directory}" + * @required + */ + private File outputDirectory; + + public void execute() + throws MojoExecutionException + { + File f = outputDirectory; + + if ( !f.exists() ) + { + f.mkdirs(); + } + + File touch = new File( f, "touch.txt" ); + + FileWriter w = null; + try + { + w = new FileWriter( touch ); + + w.write( "touch.txt" ); + } + catch ( IOException e ) + { + throw new MojoExecutionException( "Error creating file " + touch, e ); + } + finally + { + if ( w != null ) + { + try + { + w.close(); + } + catch ( IOException e ) + { + // ignore + } + } + } + } +} diff --git a/src/main/resources/templates/velocity/global/basemanager.java.vm b/src/main/resources/templates/velocity/global/basemanager.java.vm new file mode 100644 index 0000000..4bf1b3e --- /dev/null +++ b/src/main/resources/templates/velocity/global/basemanager.java.vm @@ -0,0 +1,570 @@ +##$Id: global.manager.java.vm,v 1.3 2005/10/10 20:11:46 framiere Exp $ +#parse( "header.include.vm" ) +$codewriter.setCurrentJavaFilename($pkg, "BaseManager.java") +package $pkg; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.sql.Types; +import javax.sql.DataSource; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Base data access manager. + */ +public abstract class BaseManager implements DaoManager +{ + private static final Logger logger = LoggerFactory.getLogger(BaseManager.class); + + protected BaseManager(DataSource dataSource) { + this.dataSource = dataSource; + } + + protected DataSource dataSource; + + /** + * Loads an object from the table using its key field. + * + * @return a unique object + */ + public T loadByPrimaryKey(Integer primaryKey) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Retrieves an array of objects given a sql 'where' clause. + * + * @param where The sql 'where' clause + * @return the Resulting object array + */ + public abstract T[] loadByWhere(String where) throws SQLException; + + /** + * Retrieves the unique object given a sql 'where' clause. + * + * @param where The sql 'where' clause + * @return The resulting object + */ + public T loadUniqueByWhere(String where) throws SQLException { + T[] os = loadByWhere(where); + if (os != null && os.length > 0) { + return os[0]; + } else { + return null; + } + } + + // public T createBean(); + // public int deleteByPrimaryKey(Integer id) throws SQLException; + // public T[] loadAll() throws SQLException; + // public T[] loadAll(int startRow, int numRows) throws SQLException; + // public T[] loadByWhere(String where, int[] fieldList) throws SQLException; + // public T[] loadByWhere(String where, int[] fieldList, int startRow, int numRows) throws SQLException; + // public int deleteAll() throws SQLException; + // public int deleteByWhere(String where) throws SQLException; + // public T save(T bean) throws SQLException; + // public T insert(T bean) throws SQLException; + // public T insert(T bean, boolean orUpdate) throws SQLException; + // public T insert(T bean, boolean orUpdate, boolean delayed) throws SQLException; + // public T update(T bean) throws SQLException; + // public T[] save(T[] beans) throws SQLException; + // public T[] insert(T[] beans) throws SQLException; + // public T[] update(T[] beans) throws SQLException; + // public T loadUniqueUsingTemplate(T bean) throws SQLException; + // public T[] loadUsingTemplate(T bean) throws SQLException; + // public T[] loadUsingTemplate(T bean, int startRow, int numRows) throws SQLException; + // public T[] loadUsingTemplate(T bean, int startRow, int numRows, int searchType) throws SQLException; + // public int deleteUsingTemplate(T bean) throws SQLException; + // public int countAll() throws SQLException; + // public int countWhere(String where) throws SQLException; + // public int countUsingTemplate(T bean) throws SQLException; + // public int countUsingTemplate(T bean, int startRow, int numRows) throws SQLException; + // public int countUsingTemplate(T bean, int startRow, int numRows, int searchType) throws SQLException; + // public T[] decodeResultSet(ResultSet rs, int[] fieldList, int startRow, int numRows) throws SQLException; + // public T decodeRow(ResultSet rs) throws SQLException; + // public T decodeRow(ResultSet rs, int[] fieldList) throws SQLException; + // public T metaDataDecodeRow(ResultSet rs) throws SQLException; + // public T[] loadByPreparedStatement(PreparedStatement ps) throws SQLException; + // public T[] loadByPreparedStatement(PreparedStatement ps, int[] fieldList) throws SQLException; + // public T[] loadByPreparedStatement(PreparedStatement ps, int[] fieldList, int startRow, int numRows) throws SQLException; + + /** + * @return an auto commit connection + */ + public Connection getConnection() throws SQLException + { + return dataSource.getConnection(); + } + + /** + * Releases the database connection. + */ + public void releaseConnection(Connection c) + { + if (c != null) { + try { + c.close(); + } catch (Exception e) { + logger.warn("Error releasing connection.", e); + } + } + } + + /** + * Logs a message using the underlying logwriter, if not null. + */ + public void log(String message) + { + if (logger.isTraceEnabled()) logger.trace(message); + } + + /** + * Closes the passed Statement. + */ + public void close(Statement s) + { + try + { + if (s != null) + s.close(); + } + catch (SQLException x) + { + log("Could not close statement!: " + x.toString()); + } + } + + /** + * Closes the passed ResultSet. + */ + public void close(ResultSet rs) + { + try + { + if (rs != null) + rs.close(); + } + catch (SQLException x) + { + log("Could not close result set!: " + x.toString()); + } + } + + /** + * Closes the passed Statement and ResultSet. + */ + public void close(Statement s, ResultSet rs) + { + close(rs); + close(s); + } + + //////////////////////////////////////////////////// + // Helper methods for fetching numbers using IDs or names + //////////////////////////////////////////////////// + + /** + * Retrieves an int value from the passed result set as an Integer object. + */ + public static Integer getInteger(ResultSet rs, int pos) throws SQLException + { + int i = rs.getInt(pos); + return rs.wasNull() ? (Integer)null : new Integer(i); + } + + /** + * Retrieves an int value from the passed result set as an Integer object. + */ + public static Integer getInteger(ResultSet rs, String column) throws SQLException + { + int i = rs.getInt(column); + return rs.wasNull() ? (Integer)null : new Integer(i); + } + + /** + * Set an Integer object to the passed prepared statement as an int or as null. + */ + public static void setInteger(PreparedStatement ps, int pos, Integer i) throws SQLException + { + if (i==null) + { + ps.setNull(pos, Types.INTEGER); + } + else + { + ps.setInt(pos, i.intValue()); + } + } + + /** + * Retrieves a float value from the passed result set as a Float object. + */ + public static Float getFloat(ResultSet rs, int pos) throws SQLException + { + float f = rs.getFloat(pos); + return rs.wasNull() ? (Float)null : new Float(f); + } + + /** + * Retrieves a float value from the passed result set as a Float object. + */ + public static Float getFloat(ResultSet rs, String column) throws SQLException + { + float f = rs.getFloat(column); + return rs.wasNull() ? (Float)null : new Float(f); + } + + /** + * Set a Float object to the passed prepared statement as a float or as null. + */ + public static void setFloat(PreparedStatement ps, int pos, Float f) throws SQLException + { + if (f==null) + { + ps.setNull(pos, Types.FLOAT); + } + else + { + ps.setFloat(pos, f.floatValue()); + } + } + + /** + * Retrieves a double value from the passed result set as a Double object. + */ + public static Double getDouble(ResultSet rs, int pos) throws SQLException + { + double d = rs.getDouble(pos); + return rs.wasNull() ? (Double)null : new Double(d); + } + + /** + * Retrieves a double value from the passed result set as a Double object. + */ + public static Double getDouble(ResultSet rs, String column) throws SQLException + { + double d = rs.getDouble(column); + return rs.wasNull() ? (Double)null : new Double(d); + } + + /** + * Set a Double object to the passed prepared statement as a double or as null. + */ + public static void setDouble(PreparedStatement ps, int pos, Double d) throws SQLException + { + if (d==null) + { + ps.setNull(pos, Types.DOUBLE); + } + else + { + ps.setDouble(pos, d.doubleValue()); + } + } + + /** + * Retrieves a long value from the passed result set as a Long object. + */ + public static Long getLong(ResultSet rs, int pos) throws SQLException + { + long l = rs.getLong(pos); + return rs.wasNull() ? (Long)null : new Long(l); + } + + /** + * Retrieves a long value from the passed result set as a Long object. + */ + public static Long getLong(ResultSet rs, String column) throws SQLException + { + long l = rs.getLong(column); + return rs.wasNull() ? (Long)null : new Long(l); + } + + /** + * Set a Long object to the passed prepared statement as a long or as null. + */ + public static void setLong(PreparedStatement ps, int pos, Long l) throws SQLException + { + if (l==null) + { + ps.setNull(pos, Types.BIGINT); + } + else + { + ps.setLong(pos, l.longValue()); + } + } + + /** + * Retrieves a boolean value from the passed result set as a Boolean object. + */ + public static Boolean getBoolean(ResultSet rs, int pos) throws SQLException + { + boolean b = rs.getBoolean(pos); + return rs.wasNull() ? (Boolean)null : new Boolean(b); + } + + /** + * Retrieves a boolean value from the passed result set as a Boolean object. + */ + public static Boolean getBoolean(ResultSet rs, String column) throws SQLException + { + boolean b = rs.getBoolean(column); + return rs.wasNull() ? (Boolean)null : new Boolean(b); + } + + /** + * Set a Boolean object to the passed prepared statement as a boolean or as null. + */ + public static void setBoolean(PreparedStatement ps, int pos, Boolean b) throws SQLException + { + if (b==null) + { + ps.setNull(pos, Types.BOOLEAN); + } + else + { + ps.setBoolean(pos, b.booleanValue()); + } + } + + //////////////////////////////////////////////////// + // Date helper methods + //////////////////////////////////////////////////// + + /** + * pattern for received date processing. + */ + private static final String[] patterns = new String[] + { + "EEE, dd MMM yyyy HH:mm:ss '-'S '('z')'", + "EEE, dd MMM yyyy HH:mm:ss '+'S '('z')'", + "EEE, dd MMM yyyy HH:mm:ss '-'S", + "EEE, dd MMM yyyy HH:mm:ss '+'S", + "EEE, dd MMM yyyy HH:mm:ss z", + "EEE, dd MMM yyyy HH:mm:ss Z", + "EEE, dd MMM yyyy HH:mm:ss", + "EEE, d MMM yyyy HH:mm:ss '-'S '('z')'", + "EEE, d MMM yyyy HH:mm:ss '+'S '('z')'", + "EEE, d MMM yyyy HH:mm:ss '-'S", + "EEE, d MMM yyyy HH:mm:ss '+'S", + "EEE, d MMM yyyy HH:mm:ss z", + "EEE, d MMM yyyy HH:mm:ss Z", + "EEE, d MMM yyyy HH:mm:ss", + + "EEE, dd MMM yy HH:mm:ss '-'S '('z')'", + "EEE, dd MMM yy HH:mm:ss '+'S '('z')'", + "EEE, dd MMM yy HH:mm:ss '-'S", + "EEE, dd MMM yy HH:mm:ss '+'S", + "EEE, dd MMM yy HH:mm:ss z", + "EEE, dd MMM yy HH:mm:ss Z", + "EEE, dd MMM yy HH:mm:ss", + "EEE, d MMM yy HH:mm:ss '-'S '('z')'", + "EEE, d MMM yy HH:mm:ss '+'S '('z')'", + "EEE, d MMM yy HH:mm:ss '-'S", + "EEE, d MMM yy HH:mm:ss '+'S", + "EEE, d MMM yy HH:mm:ss z", + "EEE, d MMM yy HH:mm:ss Z", + "EEE, d MMM yy HH:mm:ss", + + "dd MMM yyyy HH:mm:ss '-'S", + "dd MMM yyyy HH:mm:ss '+'S", + "dd MMM yyyy HH:mm:ss '-'S '('z')'", + "dd MMM yyyy HH:mm:ss '+'S '('z')'", + "dd MMM yyyy HH:mm:ss z", + "dd MMM yyyy HH:mm:ss Z", + "dd MMM yyyy HH:mm:ss", + + "dd MMM yyy HH:mm:ss '-'S", + "dd MMM yyy HH:mm:ss '+'S", + "dd MMM yyy HH:mm:ss '-'S '('z')'", + "dd MMM yyy HH:mm:ss '+'S '('z')'", + "dd MMM yyy HH:mm:ss z", + "dd MMM yyy HH:mm:ss Z", + "dd MMM yyy HH:mm:ss", + + "yyyy.MM.dd HH:mm:ss z", + "yyyy.MM.dd HH:mm:ss Z", + "yyyy.MM.d HH:mm:ss z", + "yyyy.MM.d HH:mm:ss Z", + "yyyy.MM.dd HH:mm:ss", + "yyyy.MM.d HH:mm:ss", + + "yy.MM.dd HH:mm:ss z", + "yy.MM.dd HH:mm:ss Z", + "yy.MM.d HH:mm:ss z", + "yy.MM.d HH:mm:ss Z", + "yy.MM.dd HH:mm:ss", + "yy.MM.d HH:mm:ss", + + "yyyy MM dd HH:mm:ss", + "yyyy MM d HH:mm:ss", + "yyyy MM dd HH:mm:ss z", + "yyyy MM dd HH:mm:ss Z", + "yyyy MM d HH:mm:ss z", + "yyyy MM d HH:mm:ss Z", + + "yy MM dd HH:mm:ss", + "yy MM d HH:mm:ss", + "yy MM dd HH:mm:ss z", + "yy MM dd HH:mm:ss Z", + "yy MM d HH:mm:ss z", + "yy MM d HH:mm:ss Z", + + "yyyy-MM-dd HH:mm:ss z", + "yyyy-MM-dd HH:mm:ss Z", + "yyyy-MM-d HH:mm:ss z", + "yyyy-MM-d HH:mm:ss Z", + "yyyy-MM-dd HH:mm:ss", + "yyyy-MM-d HH:mm:ss", + + "yy-MM-dd HH:mm:ss z", + "yy-MM-dd HH:mm:ss Z", + "yy-MM-d HH:mm:ss z", + "yy-MM-d HH:mm:ss Z", + "yy-MM-dd HH:mm:ss", + "yy-MM-d HH:mm:ss", + + "dd MMM yyyy", + "d MMM yyyy", + + "dd.MMM.yyyy", + "d.MMM.yyyy", + + "dd-MMM-yyyy", + "d-MMM-yyyy", + + "dd MM yyyy", + "d MM yyyy", + + "dd.MM.yyyy", + "d.MM.yyyy", + + "dd-MM-yyyy", + "d-MM-yyyy", + + "yyyy MM dd", + "yyyy MM d", + + "yyyy.MM.dd", + "yyyy.MM.d", + + "yyyy-MM-dd", + "yyyy-MM-d", + + "dd MMM yy", + "d MMM yy", + + "dd.MMM.yy", + "d.MMM.yy", + + "dd-MMM-yy", + "d-MMM-yy", + + "dd MM yy", + "d MM yy", + + "dd.MM.yy", + "d.MM.yy", + + "dd-MM-yy", + "d-MM-yy", + + "yy MMM dd", + "yy MMM d", + + "yy.MMM.dd", + "yy.MMM.d", + + "yy-MMM-dd", + "yy-MMM-d", + + "yy MMM dd", + "yy MMM d", + + "yy.MMM.dd", + "yy.MMM.d", + + "yy-MMM-dd", + "yy-MMM-d", + + "EEE dd, MMM yyyy", // ex: Wed 19, Feb 2003 + + "EEE dd, MMM yy" // ex: Wed 19, Feb 03 + }; + + + /** + * get a date from a date string representation in one of the registered formats + * @param strDate the date as string. If (null or empty) or correct pattern was not found + * @return Date object + */ + static public java.util.Date getDateFromString(String strDate) + { + if (strDate != null) + strDate = strDate.trim(); + + SimpleDateFormat pSimpleDateFormat = new SimpleDateFormat(""); + java.util.Date dReceivedDate = Calendar.getInstance().getTime(); + + if (strDate != null && "".equals(strDate) == false) + { + for (int i=0; i +{ + private static final Logger logger = LoggerFactory.getLogger(CachingManager.class); + + private static final long DEFAULT_EXPIRE = 3600000l; //1 hour + + public CachingManager(DaoManager manager) + { + this.manager = manager; + this.cache = new HashMap(); + this.expiration = DEFAULT_EXPIRE; + } + + public CachingManager(DaoManager manager, Map cache) + { + this.manager = manager; + this.cache = cache; + this.expiration = DEFAULT_EXPIRE; + } + + public CachingManager(DaoManager manager, Map cache, long expiration) + { + this.manager = manager; + this.cache = cache; + this.expiration = expiration; + } + + private DaoManager manager; + private Map cache; + private long expiration; + + /** + * Retrieves the bean via primary key. + * @param primaryKey The Integer primary key. + * @return The bean or null. + */ + public T get(Integer primaryKey) + { + CacheEntry entry = (CacheEntry)cache.get(primaryKey); + if (entry != null && entry.valid()) return (T)entry.getBean(); + try { + Object o = manager.loadByPrimaryKey(primaryKey); + if (o != null) { + cache.put(primaryKey, new CacheEntry(primaryKey, o, expiration)); + return (T)o; + } + } catch (Exception e) { + logger.error("Error loading bean from cache: ", e); + } + return null; + } + + /** + * Retrieves the bean via primary key. + * @param where The WHERE clause. + * @return The bean or null. + */ + public T[] get(String where) + { + CacheEntry entry = (CacheEntry)cache.get(where); + if (entry != null && entry.valid()) return (T[])entry.getBean(); + try { + Object[] o = manager.loadByWhere(where); + if (o != null) { + logger.trace("CACHE PUT: "+where); + cache.put(where, new CacheEntry(where, o, expiration)); + return (T[])o; + } + } catch (Exception e) { + logger.error("Error loading bean from cache: ", e); + } + return null; + } + + private class CacheEntry { + + public CacheEntry(Object key, Object value, long expiration) { + this.key = key; + this.value = value; + this.loaded = System.currentTimeMillis(); + this.expiration = expiration; + } + + private Object key; + private Object value; + public Object getBean() { return this.value; } + private long loaded; + private long expiration; + + public boolean valid() + { + return System.currentTimeMillis()-loaded < expiration; + } + } + +} diff --git a/src/main/resources/templates/velocity/global/daobean.java.vm b/src/main/resources/templates/velocity/global/daobean.java.vm new file mode 100644 index 0000000..2a5f160 --- /dev/null +++ b/src/main/resources/templates/velocity/global/daobean.java.vm @@ -0,0 +1,15 @@ +##$Id: generated.bean.java.vm,v 1.1 2005/10/12 12:37:58 framiere Exp $ +#parse( "header.include.vm" ) +$codewriter.setCurrentJavaFilename($pkg, "DaoBean.java") +package $pkg; + +import java.util.Map; + +public interface DaoBean +{ + public boolean isNew(); + public boolean isModified(); + public void resetIsModified(); + public Map getDictionnary(); + public Map getPkDictionnary(); +} diff --git a/src/main/resources/templates/velocity/global/daomanager.java.vm b/src/main/resources/templates/velocity/global/daomanager.java.vm new file mode 100755 index 0000000..852ba4c --- /dev/null +++ b/src/main/resources/templates/velocity/global/daomanager.java.vm @@ -0,0 +1,52 @@ +##$Id: global.manager.java.vm,v 1.3 2005/10/10 20:11:46 framiere Exp $ +#parse( "header.include.vm" ) +$codewriter.setCurrentJavaFilename($pkg, "DaoManager.java") +package $pkg; + +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; + +/** + * Data access manager. + */ +public interface DaoManager +{ + // public T createBean(); + public String getTableName(); + public T loadByPrimaryKey(Integer id) throws SQLException; + // public int deleteByPrimaryKey(Integer id) throws SQLException; + // public T[] loadAll() throws SQLException; + // public T[] loadAll(int startRow, int numRows) throws SQLException; + public T[] loadByWhere(String where) throws SQLException; + // public T[] loadByWhere(String where, int[] fieldList) throws SQLException; + // public T[] loadByWhere(String where, int[] fieldList, int startRow, int numRows) throws SQLException; + public T loadUniqueByWhere(String where) throws SQLException; + // public int deleteAll() throws SQLException; + // public int deleteByWhere(String where) throws SQLException; + // public T save(T bean) throws SQLException; + // public T insert(T bean) throws SQLException; + // public T insert(T bean, boolean orUpdate) throws SQLException; + // public T insert(T bean, boolean orUpdate, boolean delayed) throws SQLException; + // public T update(T bean) throws SQLException; + // public T[] save(T[] beans) throws SQLException; + // public T[] insert(T[] beans) throws SQLException; + // public T[] update(T[] beans) throws SQLException; + // public T loadUniqueUsingTemplate(T bean) throws SQLException; + // public T[] loadUsingTemplate(T bean) throws SQLException; + // public T[] loadUsingTemplate(T bean, int startRow, int numRows) throws SQLException; + // public T[] loadUsingTemplate(T bean, int startRow, int numRows, int searchType) throws SQLException; + // public int deleteUsingTemplate(T bean) throws SQLException; + // public int countAll() throws SQLException; + // public int countWhere(String where) throws SQLException; + // public int countUsingTemplate(T bean) throws SQLException; + // public int countUsingTemplate(T bean, int startRow, int numRows) throws SQLException; + // public int countUsingTemplate(T bean, int startRow, int numRows, int searchType) throws SQLException; + // public T[] decodeResultSet(ResultSet rs, int[] fieldList, int startRow, int numRows) throws SQLException; + // public T decodeRow(ResultSet rs) throws SQLException; + // public T decodeRow(ResultSet rs, int[] fieldList) throws SQLException; + // public T metaDataDecodeRow(ResultSet rs) throws SQLException; + // public T[] loadByPreparedStatement(PreparedStatement ps) throws SQLException; + // public T[] loadByPreparedStatement(PreparedStatement ps, int[] fieldList) throws SQLException; + // public T[] loadByPreparedStatement(PreparedStatement ps, int[] fieldList, int startRow, int numRows) throws SQLException; +} diff --git a/src/main/resources/templates/velocity/global/managerfactory.java.vm b/src/main/resources/templates/velocity/global/managerfactory.java.vm new file mode 100644 index 0000000..f005c02 --- /dev/null +++ b/src/main/resources/templates/velocity/global/managerfactory.java.vm @@ -0,0 +1,29 @@ +package com.pickstream.model.sports; + +import java.lang.reflect.Constructor; +import javax.sql.DataSource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Factory for managers. + * @author garth + */ +public class ManagerFactory +{ + private static final Logger logger = LoggerFactory.getLogger(ManagerFactory.class); + + public ManagerFactory(DataSource dataSource) { + this.dataSource = dataSource; + } + + protected DataSource dataSource; + + public Object getManager(Class clazz) throws Exception { + logger.trace("Attempting to load Manager for {}.", clazz); + Constructor ctr = clazz.getConstructor(DataSource.class); + Object o = ctr.newInstance(dataSource); + return o; + } + +} diff --git a/src/main/resources/templates/velocity/includes/header.include.vm b/src/main/resources/templates/velocity/includes/header.include.vm new file mode 100755 index 0000000..70dda68 --- /dev/null +++ b/src/main/resources/templates/velocity/includes/header.include.vm @@ -0,0 +1,8 @@ +##$Id: header.include.vm,v 1.5 2005/10/10 20:11:47 framiere Exp $ +#set ( $db = $codewriter.db ) +#set ( $allPackages = $db.getAllPackages() ) +#set ( $widgetPkg = "${pkg}.widget") +#set ( $SPACE = " ") +#set ( $IMPORT_BLOCK = "imports") +#set ( $EXTENDS_BLOCK = "extends") +#set ( $CLASS_BLOCK = "class") diff --git a/src/main/resources/templates/velocity/includes/table.variables.include.vm b/src/main/resources/templates/velocity/includes/table.variables.include.vm new file mode 100755 index 0000000..5b21b0a --- /dev/null +++ b/src/main/resources/templates/velocity/includes/table.variables.include.vm @@ -0,0 +1,21 @@ +##$Id: table.variables.include.vm,v 1.7 2005/10/10 22:06:26 framiere Exp $ +#set ( $tablename = $codewriter.tableName() ) +#set ( $tableName = $strUtil.convertName($codewriter.tableName()) ) +#set ( $columns = $codewriter.getColumns() ) +#set ( $foreignKeys = $codewriter.getForeignKeys() ) +#set ( $importedKeys = $codewriter.getImportedKeys() ) +#set ( $primaryKeys = $codewriter.getPrimaryKeys() ) +#set ( $coreClass = $strUtil.getCoreClass($table) ) +#set ( $managerClass = $strUtil.getManagerClass($table) ) +#set ( $beanClass = $strUtil.getBeanClass($table) ) +#set ( $factoryClass = $strUtil.getFactoryClass($table) ) +#set ( $httpFactoryClass = $strUtil.getHttpFactoryClass($table) ) +#set ( $comparatorClass = $strUtil.getComparatorClass($table) ) +#set ( $listenerClass = $strUtil.getListenerClass($table) ) +#set ( $rendererClass = $strUtil.getRendererClass($table) ) +#set ( $widgetFactoryClass = $strUtil.getWidgetFactoryClass($table) ) +#set ( $widgetClass = $strUtil.getWidgetClass($table) ) +#set ( $linkedTables = $table.getLinkedTables()) +#set ( $linkedPackages = $table.getLinkedPackages()) +#set ( $pkgPath = $table.getPackagePath()) +#set ( $Q = '"' ) diff --git a/src/main/resources/templates/velocity/table/bean.java.vm b/src/main/resources/templates/velocity/table/bean.java.vm new file mode 100755 index 0000000..c993cfe --- /dev/null +++ b/src/main/resources/templates/velocity/table/bean.java.vm @@ -0,0 +1,247 @@ +##$Id: bean.java.vm,v 1.8 2005/10/17 09:09:59 framiere Exp $ +#parse( "header.include.vm" ) +#parse( "table.variables.include.vm" ) +$codewriter.setCurrentJavaFilename("$table.getPackage()", "${beanClass}.java") +package $table.getPackage(); + +import $pkg.*; + +import java.io.Serializable; +import java.util.Map; +import java.util.HashMap; + +/** + * $beanClass is a mapping of $table.getName() Table. +#if ( $table.getRemarks().length() > 0 ) + *
Meta Data Information (in progress): + *

    + *
  • comments: $table.getRemarks()
  • + *
+#end +*/ +public class $beanClass +#if ($extendsClass) + extends $extendsClass +#end + implements Serializable +#if ($implementsClasses) + #foreach( $implements in $implementsClasses )$implements#end +#end +{ +#foreach ( $column in $columns ) +#set( $columnfield = $strUtil.getVarName($column)) + + private $column.getJavaType() $strUtil.getVarName($column); + private boolean $strUtil.getModifiedVarName( $column ) = false; + private boolean $strUtil.getInitializedVarName( $column ) = false; + +#end + private boolean _isNew = true; + + /** + * Do not use this constructor directly, please use the factory method + * available in the associated manager. + */ + $beanClass() + { + } + +#foreach ($column in $columns) + /** + * Getter method for $strUtil.getVarName($column). + *
+#if ( $column.isPrimaryKey() ) + * PRIMARY KEY.
+#end + * Meta Data Information (in progress): + *
    + *
  • full name: $column.getFullName() +#if ( $column.getPointsTo() ) + *
  • foreign key: ${column.PointsTo.TableName}.${column.PointsTo.getName()} +#end +#if ( $column.getRemarks().length() > 0 ) + *
  • comments: $column.getRemarks() +#end +#if ( $column.DefaultValue.length() > 0 ) + *
  • default value: $column.DefaultValue +#end + *
  • column size: $column.getSize() + *
  • jdbc type returned by the driver: $column.getJavaTypeAsTypeName() + *
+ * + * @return the value of $strUtil.getVarName($column) + */ + public $column.getJavaType() $strUtil.getGetMethod($column)() + { + return $strUtil.getVarName($column); + } + + /** + * Setter method for $strUtil.getVarName($column). + *
+#if ( $column.hasCompareTo() ) + * The new value is set only if compareTo() says it is different, + * or if one of either the new value or the current value is null. + * In case the new value is different, it is set and the field is marked as 'modified'. +#else + * Attention, there will be no comparison with current value which + * means calling this method will mark the field as 'modified' in all cases. +#end + * + * @param newVal the new value to be assigned to $strUtil.getVarName($column) + */ + public void ${strUtil.getSetMethod($column)}($column.getJavaType() newVal) + { +#if ($column.hasCompareTo()) + if ((newVal != null && this.$strUtil.getVarName($column) != null && (newVal.compareTo(this.$strUtil.getVarName($column)) == 0)) || + (newVal == null && this.$strUtil.getVarName($column) == null && $strUtil.getInitializedVarName($column))) { + return; + } +#elseif ( $column.useEqualsInSetter() ) + if ((newVal != null && this.$strUtil.getVarName($column) != null && newVal.equals(this.$strUtil.getVarName($column))) || + (newVal == null && this.$strUtil.getVarName($column) == null && $strUtil.getInitializedVarName($column))) { + return; + } +#end + this.$strUtil.getVarName($column) = newVal; + $strUtil.getModifiedVarName($column) = true; + $strUtil.getInitializedVarName($column) = true; + } + +#if ( $strUtil.hasPrimaryType($column) ) + /** + * Setter method for $strUtil.getVarName($column). + *
+ * Convenient for those who do not want to deal with Objects for primary types. + * + * @param newVal the new value to be assigned to $strUtil.getVarName($column) + */ + public void $strUtil.getSetMethod($column)($strUtil.getJavaPrimaryType($column) newVal) + { + $strUtil.getSetMethod($column)(new $column.getJavaType()(newVal)); + } + +#end + /** + * Determines if the $strUtil.getVarName($column) has been modified. + * + * @return true if the field has been modified, false if the field has not been modified + */ + public boolean $strUtil.getModifiedMethod($column)() + { + return $strUtil.getModifiedVarName($column); + } + + /** + * Determines if the $strUtil.getVarName($column) has been initialized. + *
+ * It is useful to determine if a field is null on purpose or just because it has not been initialized. + * + * @return true if the field has been initialized, false otherwise + */ + public boolean $strUtil.getInitializedMethod($column)() + { + return $strUtil.getInitializedVarName($column); + } + +#end + /** + * Determines if the current object is new. + * + * @return true if the current object is new, false if the object is not new + */ + public boolean isNew() + { + return _isNew; + } + + /** + * Specifies to the object if it has been set as new. + * + * @param isNew the boolean value to be assigned to the isNew field + */ + public void isNew(boolean isNew) + { + this._isNew = isNew; + } + + /** + * Determines if the object has been modified since the last time this method was called. + *
+ * We can also determine if this object has ever been modified since its creation. + * + * @return true if the object has been modified, false if the object has not been modified + */ + public boolean isModified() + { + return #foreach ( $column in $columns )#if ( $velocityCount == 1 )$strUtil.getModifiedVarName($column)#else || + $strUtil.getModifiedVarName($column)#end#end; + } + + /** + * Resets the object modification status to 'not modified'. + */ + public void resetIsModified() + { +#foreach ( $column in $columns ) + $strUtil.getModifiedVarName($column) = false; +#end + } + + /** + * Copies the passed bean into the current bean. + * + * @param bean the bean to copy into the current bean + */ + public void copy($beanClass bean) + { +#foreach ( $column in $columns ) + $strUtil.getSetMethod($column)(bean.$strUtil.getGetMethod($column)()); +#end + } + + /** + * Returns the object string representation. + * + * @return the object as a string + */ + public String toString() + { + return "\n[$tablename] " +#foreach ( $column in $columns ) + + "\n - $column.getFullName() = " + ($strUtil.getInitializedVarName($column) ? ("[" + ($strUtil.getVarName($column) == null ? null : ${strUtil.getVarName($column)}.toString()) + "]") : "not initialized") + "" +#end + ; + } + + /** + * return a dictionary of the object + */ + public Map getDictionary() + { + Map dictionary = new HashMap(); +#foreach ( $column in $columns ) + dictionary.put("$column.getName().toLowerCase()", $strUtil.getGetMethod($column)() == null ? "" : ${strUtil.getGetMethod($column)}().toString()); +#end + return dictionary; + } + + /** + * return a dictionary of the pk columns +#if ( $table.countPrimaryKeys() == 0) + * no primary key, the regular dictionary is returned +#end + */ + public Map getPkDictionary() + { +#if ( $table.countPrimaryKeys() == 0) + return getDictionary(); +#else + Map dictionary = new HashMap(); +#foreach ( $column in $primaryKeys ) + dictionary.put("$column.getName().toLowerCase()", $strUtil.getGetMethod($column)() == null ? "" : ${strUtil.getGetMethod($column)}().toString()); +#end + return dictionary; +#end + } +} diff --git a/src/main/resources/templates/velocity/table/comparator.java.vm b/src/main/resources/templates/velocity/table/comparator.java.vm new file mode 100755 index 0000000..8576280 --- /dev/null +++ b/src/main/resources/templates/velocity/table/comparator.java.vm @@ -0,0 +1,104 @@ +##$Id: comparator.java.vm,v 1.2 2005/10/10 20:11:48 framiere Exp $ +#parse( "header.include.vm" ) +#parse( "table.variables.include.vm" ) +$codewriter.setCurrentJavaFilename("$table.getPackage()", "${comparatorClass}.java") +package $table.getPackage(); + +import java.util.Comparator; + +import $pkg.*; + +/** + * Comparator class is used to sort the $beanClass objects. + */ +public class $comparatorClass implements Comparator +{ + /** + * Holds the field on which the comparison is performed. + */ + private int iType; + /** + * Value that will contain the information about the order of the sort: normal or reversal. + */ + private boolean bReverse; + + /** + * Constructor class for $comparatorClass. + *
+ * Example: + *
+ * Arrays.sort(pArray, new $comparatorClass(${coreClass}Manager.$columns.get(0).getConstName(), bReverse)); + * + * @param iType the field from which you want to sort + *
+ * Possible values are: + *
    +#foreach( $column in $columns ) +#if ( $column.hasCompareTo() ) + *
  • ${managerClass}.ID_$column.getConstName() +#end +#end + *
+ */ + public $comparatorClass(int iType) + { + this(iType, false); + } + + /** + * Constructor class for ${comparatorClass}. + *
+ * Example: + *
+ * Arrays.sort(pArray, new $comparatorClass(${coreClass}Manager.$columns.get(0).getConstName(), bReverse)); + * + * @param iType the field from which you want to sort. + *
+ * Possible values are: + *
    +#foreach( $column in $columns ) + *
  • ${managerClass}.ID_$column.getConstName() +#end + *
+ * + * @param bReverse set this value to true, if you want to reverse the sorting results + */ + public $comparatorClass(int iType, boolean bReverse) + { + this.iType = iType; + this.bReverse = bReverse; + } + + /** + * Implementation of the compare method. + */ + public int compare(Object pObj1, Object pObj2) + { + $beanClass b1 = ($beanClass)pObj1; + $beanClass b2 = ($beanClass)pObj2; + int iReturn = 0; + switch(iType) + { +## I need to add a try catch here?????? +#foreach( $column in $columns ) +#set ( $getMethod = $strUtil.getGetMethod( $column ) ) +#if ( $column.hasCompareTo() ) + case ${managerClass}.ID_$column.getConstName(): + if (b1.$getMethod() == null && b2.$getMethod() != null) { + iReturn = -1; + } else if (b1.$getMethod() == null && b2.$getMethod() == null) { + iReturn = 0; + } else if (b1.$getMethod() != null && b2.$getMethod() == null) { + iReturn = 1; + } else { + iReturn = b1.$getMethod().compareTo(b2.$getMethod()); + } + break; +#end +#end + default: + throw new IllegalArgumentException("Type passed for the field is not supported"); + } + + return bReverse ? (-1 * iReturn) : iReturn; + }} diff --git a/src/main/resources/templates/velocity/table/listener.java.vm b/src/main/resources/templates/velocity/table/listener.java.vm new file mode 100755 index 0000000..cd2b73b --- /dev/null +++ b/src/main/resources/templates/velocity/table/listener.java.vm @@ -0,0 +1,47 @@ +##$Id: listener.java.vm,v 1.2 2005/10/10 20:11:48 framiere Exp $ +#parse( "header.include.vm" ) +#parse( "table.variables.include.vm" ) +$codewriter.setCurrentJavaFilename("$table.getPackage()", "${listenerClass}.java") +package $table.getPackage(); + +import java.sql.SQLException; + +import $pkg.*; + +/** + * Listener that is notified of $tablename table changes. + */ +public interface $listenerClass +{ + /** + * Invoked just before inserting a $beanClass record into the database. + * + * @param pObject the $beanClass that is about to be inserted + */ + public void beforeInsert($beanClass bean) throws SQLException; + + + /** + * Invoked just after a $beanClass record is inserted in the database. + * + * @param pObject the $beanClass that was just inserted + */ + public void afterInsert($beanClass bean) throws SQLException; + + + /** + * Invoked just before updating a $beanClass record in the database. + * + * @param pObject the $beanClass that is about to be updated + */ + public void beforeUpdate($beanClass bean) throws SQLException; + + + /** + * Invoked just after updating a $beanClass record in the database. + * + * @param pObject the $beanClass that was just updated + */ + public void afterUpdate($beanClass bean) throws SQLException; + +} diff --git a/src/main/resources/templates/velocity/table/manager.java.vm b/src/main/resources/templates/velocity/table/manager.java.vm new file mode 100644 index 0000000..c62a8b7 --- /dev/null +++ b/src/main/resources/templates/velocity/table/manager.java.vm @@ -0,0 +1,1280 @@ +##$Id: manager.java.vm,v 1.12 2005/10/17 09:09:59 framiere Exp $ +#parse( "header.include.vm" ) +#parse( "table.variables.include.vm" ) +$codewriter.setCurrentJavaFilename("$table.getPackage()", "${managerClass}.java") +package $table.getPackage(); + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.sql.Types; +import javax.sql.DataSource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +#foreach ($linkedPackage in $linkedPackages) +import ${linkedPackage}.*; +#end + +/** + * Handles database calls (save, load, count, etc...) for the $tablename table. +#if ( $codewriter.hasRemarks() ) + * Remarks: $codewriter.getRemarks() +#end + */ +public class $managerClass extends BaseManager<$beanClass> +{ + private static final Logger log = LoggerFactory.getLogger(${managerClass}.class.getName()); + + /* set =QUERY for loadUsingTemplate */ + static public final int SEARCH_EXACT = 0; + /* set %QUERY% for loadLikeTemplate */ + static public final int SEARCH_LIKE = 1; + /* set %QUERY for loadLikeTemplate */ + static public final int SEARCH_STARTING_LIKE = 2; + /* set QUERY% for loadLikeTemplate */ + static public final int SEARCH_ENDING_LIKE = 3; + +#foreach ( $column in $columns ) #set ( $vcmo = $velocityCount - 1 ) + /** + * Identify the $column.getName() field. + */ + public static final int ID_$column.getConstName() = $vcmo; + +#end + /** + * Contains all the full fields of the $tablename table. + */ + private static final String[] FULL_FIELD_NAMES = + { +#foreach ( $column in $columns ) + #if ( $velocityCount > 1 ),#end"$column.getFullName()" +#end + }; + + /** + * Contains all the fields of the $tablename table. + */ + private static final String[] FIELD_NAMES = + { +#foreach ( $column in $columns ) + #if ( $velocityCount > 1 ),#end"$column.getName()" +#end + }; + + /** + * Field that contains the comma separated fields of the $tablename table. + */ + public static final String ALL_FULL_FIELDS = #foreach( $column in $columns ) +#if ( $velocityCount > 1 ) + + + ",#else"#end$column.getFullName()"#end; + + /** + * Field that contains the comma separated fields of the $tablename table. + */ + public static final String ALL_FIELDS = #foreach( $column in $columns ) +#if ( $velocityCount > 1 ) + + + ",#else"#end$column.getName()"#end; + + /** + * Constructor + */ + public $managerClass(DataSource dataSource) + { + super(dataSource); + } + + /** + * Creates a new $beanClass instance. + * + * @return the new $beanClass + */ + public $beanClass create$beanClass() + { + return new $beanClass(); + } + + /** + * Table managed by this manager + * + * @return tablename + */ + public String getTableName() + { + return "$tablename"; + } + +#if ( $primaryKeys.size() > 0 ) + ////////////////////////////////////// + // PRIMARY KEY METHODS + ////////////////////////////////////// + +#set ( $keys = "" ) +#foreach ( $pk in $primaryKeys ) +#if ( $velocityCount > 1 )#set( $keys = "$keys, " )#end +#set ( $keys = "$keys${pk.getJavaType()} $strUtil.getVarName($pk)" ) +#end +##set ( $noWhereSelect = "SELECT \" + ALL_FIELDS + \" FROM \" + $tablename" ) +##set ( $baseSelect = "$noWhereSelect WHERE " ) +#set ( $sql = "" ) +#foreach( $pk in $primaryKeys ) +#if ( $velocityCount > 1 )#set ( $sql = "$sql and " )#end +#set ( $sql = "$sql$pk.getName()=?" ) +#end + /** + * Loads a $beanClass from the $tablename using its key fields. + * + * @return a unique $beanClass + */ + //1 + public $beanClass loadByPrimaryKey($keys) throws SQLException + { + Connection c = null; + PreparedStatement ps = null; + try + { + c = getConnection(); + StringBuffer sql = new StringBuffer("SELECT " + ALL_FIELDS + " FROM $tablename WHERE $sql"); + if (log.isTraceEnabled()) log.trace("loadByPrimaryKey: " + sql); + ps = c.prepareStatement(sql.toString(), + ResultSet.TYPE_SCROLL_INSENSITIVE, + ResultSet.CONCUR_READ_ONLY); +#foreach( $pk in $primaryKeys ) + $pk.getPreparedStatementMethod($strUtil.getVarName($pk), $velocityCount) +#end + $beanClass pReturn[] = loadByPreparedStatement(ps); + if (pReturn.length < 1) + return null; + else + return pReturn[0]; + } + finally + { + close(ps); + releaseConnection(c); + } + } + +#set ( $sql = "" ) +#foreach( $pk in $primaryKeys ) +#if ( $velocityCount > 1 )#set ( $sql = "$sql and " )#end +#set ( $sql = "$!sql$pk.getName()=?" ) +#end + /** + * Deletes rows according to its keys. + * + * @return the number of deleted rows + */ + //2 + public int deleteByPrimaryKey($keys) throws SQLException + { + Connection c = null; + PreparedStatement ps = null; + try + { + c = getConnection(); + StringBuffer sql = new StringBuffer("DELETE FROM $tablename WHERE $sql"); + if (log.isTraceEnabled()) log.trace("loadByPrimaryKey: " + sql); + ps = c.prepareStatement(sql.toString(), + ResultSet.TYPE_SCROLL_INSENSITIVE, + ResultSet.CONCUR_READ_ONLY); +#foreach( $pk in $primaryKeys ) + $pk.getPreparedStatementMethod($strUtil.getVarName($pk), $velocityCount) +#end + return ps.executeUpdate(); + } + finally + { + close(ps); + releaseConnection(c); + } + } +#end +## ====================================================== +## xForeignKeys template +## ====================================================== +#set ( $keysDone = [] ) +#set ( $keysImported = [] ) +#foreach ($impKey in $foreignKeys) +#if ( $velocityCount == 1 ) + + ////////////////////////////////////// + // GET/SET FOREIGN KEY BEAN METHOD + ////////////////////////////////////// +#end +#set ( $importedtable = $impKey.getForeignColumn().getTableName() ) +#set ( $importedClass = "${strUtil.getBeanClass($importedtable)}" ) +#set ( $importedClassManager = "${strUtil.getManagerClass($importedtable)}" ) +#if ( !$keysImported.contains( $importedClass ) ) +#if ( $keysImported.add($importedClass) )#*squelch*##end + /** + * Retrieves the $importedClass object from the $tablename.$impKey.getName() field. + * + * @param bean the $beanClass + * @return the associated $importedClass bean + */ + //3 GET IMPORTED + public $importedClass[] get${importedClass}s($beanClass bean) throws SQLException + { + $importedClass other = ${importedClassManager}.getInstance().create${importedClass}(); + other.${strUtil.getSetMethod($impKey.getForeignColumn())}(bean.${strUtil.getGetMethod($impKey)}()); + return ${importedClassManager}.getInstance().loadUsingTemplate(other); + } + + /** + * Associates the $beanClass object to the $importedClass object. + * + * @param bean the $beanClass object to use + * @param beanToSet the $importedClass object to associate to the $beanClass + * @return the associated $importedClass bean + */ + //4 SET IMPORTED + public $beanClass set${importedClass}($beanClass bean,$importedClass beanToSet) + { + bean.${strUtil.getSetMethod($impKey)}(beanToSet.${strUtil.getGetMethod($impKey.getForeignColumn())}()); + return bean; + } + +#end +#end + + ////////////////////////////////////// + // LOAD ALL + ////////////////////////////////////// + + /** + * Loads all the rows from $tablename. + * + * @return an array of $managerClass bean + */ + //5 + public $beanClass[] loadAll() throws SQLException + { + return loadUsingTemplate(null); + } + + + /** + * Loads the given number of rows from $tablename, given the start row. + * + * @param startRow the start row to be used (first row = 1, last row = -1) + * @param numRows the number of rows to be retrieved (all rows = a negative number) + * @return an array of $managerClass bean + */ + //6 + public $beanClass[] loadAll(int startRow, int numRows) throws SQLException + { + return loadUsingTemplate(null, startRow, numRows); + } + + ////////////////////////////////////// + // SQL 'WHERE' METHOD + ////////////////////////////////////// + /** + * Retrieves an array of $beanClass given a sql 'where' clause. + * + * @param where the sql 'where' clause + * @return the resulting $beanClass table + */ + //7 + public $beanClass[] loadByWhere(String where) throws SQLException + { + return loadByWhere(where, null); + } + + /** + * Retrieves an array of $beanClass given a sql where clause, and a list of fields. + * It is up to you to pass the 'WHERE' in your where clausis. + * + * @param where the sql 'WHERE' clause + * @param fieldList array of field's ID + * @return the resulting $beanClass table + */ + //8 + public $beanClass[] loadByWhere(String where, int[] fieldList) throws SQLException + { + return loadByWhere(where, fieldList, 1, -1); + } + + /** + * Retrieves an array of $beanClass given a sql where clause and a list of fields, and startRow and numRows. + * It is up to you to pass the 'WHERE' in your where clausis. + * + * @param where the sql 'where' clause + * @param startRow the start row to be used (first row = 1, last row = -1) + * @param numRows the number of rows to be retrieved (all rows = a negative number) + * @param fieldList table of the field's associated constants + * @return the resulting $beanClass table + */ + //9 + public $beanClass[] loadByWhere(String where, int[] fieldList, int startRow, int numRows) throws SQLException + { + String sql = null; + if(fieldList == null) + sql = "SELECT " + ALL_FIELDS + " FROM $tablename " + where; + else + { + StringBuffer buff = new StringBuffer(128); + buff.append("SELECT "); + for(int i = 0; i < fieldList.length; i++) + { + if(i != 0) + buff.append(","); + buff.append(FIELD_NAMES[fieldList[i]]); + } + buff.append(" FROM $tablename "); + buff.append(where); + sql = buff.toString(); + buff = null; + } + Connection c = null; + Statement st = null; + ResultSet rs = null; + if (log.isTraceEnabled()) log.trace("loadByWhere: " + sql); + try + { + c = getConnection(); + st = c.createStatement(); + rs = st.executeQuery(sql); + return decodeResultSet(rs, fieldList, startRow, numRows); + } + finally + { + sql = null; + close(st, rs); + releaseConnection(c); + } + } + + + /** + * Deletes all rows from $tablename table. + * @return the number of deleted rows. + */ + //10 + public int deleteAll() throws SQLException + { + return deleteByWhere(""); + } + + + /** + * Deletes rows from the $tablename table using a 'where' clause. + * It is up to you to pass the 'WHERE' in your where clausis. + *
Attention, if 'WHERE' is omitted it will delete all records. + * + * @param where the sql 'where' clause + * @return the number of deleted rows + */ + //11 + public int deleteByWhere(String where) throws SQLException + { + Connection c = null; + PreparedStatement ps = null; + + try + { + c = getConnection(); + StringBuffer sql = new StringBuffer("DELETE FROM $tablename " + where); + if (log.isTraceEnabled()) log.trace("deleteByWhere: " + sql); + ps = c.prepareStatement(sql.toString()); + return ps.executeUpdate(); + } + finally + { + close(ps); + releaseConnection(c); + } + } + + //_____________________________________________________________________ + // + // SAVE + //_____________________________________________________________________ + /** + * Saves the $beanClass bean into the database. + * + * @param bean the $beanClass bean to be saved + */ + //12 + public $beanClass save($beanClass bean) throws SQLException + { + if (bean.isNew()) + return insert(bean); + else + return update(bean); + } + + /** + * Insert the $beanClass bean into the database. + * + * @param bean the $beanClass bean to be saved + */ + //13 + public $beanClass insert($beanClass bean) throws SQLException + { + return insert(bean, false); + } + + /** + * Insert the $beanClass bean into the database. + * + * @param bean the $beanClass bean to be saved + * @param orUpdate on duplicate key update + */ + //13 + public $beanClass insert($beanClass bean, boolean orUpdate) throws SQLException + { + return insert(bean, orUpdate, false); + } + + + /** + * Insert the $beanClass bean into the database. + * + * @param bean the $beanClass bean to be saved + * @param orUpdate on duplicate key update + * @param delayed use INSERT DELAYED and don't get generated keys + */ + //13 + public $beanClass insert($beanClass bean, boolean orUpdate, boolean delayed) throws SQLException + { + // mini checks + if (!bean.isModified()) { + return bean; // should not we log something ? + } + if (!bean.isNew()){ + return update(bean); + } + + Connection c = null; + PreparedStatement ps = null; + StringBuffer sql = null; + + try + { + c = getConnection(); +##-------------writePreInsert +#set( $genKeyRetrieve = $codewriter.getProperty("generatedkey.retrieve", "") ) +#set ( $hint = $codewriter.getProperty("generatedkey.statement").replaceAll("
", $tablename) ) +#if ( $primaryKeys.size() > 0 )#set ( $pKey = $primaryKeys.get(0) )#end +#if ( $genKeyRetrieve == "before" && $primaryKeys.size() == 1 && $pKey.isColumnNumeric() ) + if (!bean.$strUtil.getModifiedMethod($pKey)()) + { + StringBuffer hint = new StringBuffer("$hint"); + if (log.isTraceEnabled()) log.trace("generatedKey : " + hint); + + ps = c.prepareStatement(hint.toString()); + ResultSet rs = null; + try + { + rs = ps.executeQuery(); + if(rs.next()) + bean.$strUtil.getSetMethod($pKey)($pKey.getResultSetMethodObject("1")); + else + log("ATTENTION: Could not retrieve generated key!"); + } + finally + { + close(ps, rs); + ps=null; + } + } +#end +##------------/writePreInsert + int _dirtyCount = 0; +#set ( $isPresentLock = $codewriter.isPresentLock( $columns ) ) +#if ( $isPresentLock ) +#set ($lockColumn = $codewriter.getLockColumn($columns)) + bean.$strUtil.getSetMethod($lockColumn)(new $lockColumn.getJavaType()(String.valueOf(System.curentTimeMillis()))); + +#end + sql = new StringBuffer(); + if (delayed) sql.append("INSERT DELAYED into $tablename ("); + else sql.append("INSERT into $tablename ("); + +#foreach( $column in $columns ) + if (bean.$strUtil.getModifiedMethod($column)()) { + if (_dirtyCount>0) { + sql.append(","); + } + sql.append("$column.getName()"); + _dirtyCount++; + } + +#end + sql.append(") values ("); + if(_dirtyCount > 0) { + sql.append("?"); + for(int i = 1; i < _dirtyCount; i++) { + sql.append(",?"); + } + } + sql.append(")"); + +#if ( $genKeyRetrieve == "auto" ) +#set( $prestArgs = "Statement.RETURN_GENERATED_KEYS" ) +#else +#set( $prestArgs = "ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY" ) +#end + + if (orUpdate) { + sql.append(" ON duplicate KEY UPDATE "); + boolean useComma=false; +#foreach( $column in $columns ) + + if (bean.$strUtil.getModifiedMethod($column)()) { + if (useComma) { + sql.append(","); + } else { + useComma=true; + } + sql.append("$column.getName()").append("=VALUES(").append("$column.getName()").append(")"); + } +#end + + } + + if (log.isTraceEnabled()) log.trace("insert : " + sql.toString()); + + ps = c.prepareStatement(sql.toString(), + $prestArgs); + + fillPreparedStatement(ps, bean, SEARCH_EXACT); + + ps.executeUpdate(); +##------------------writePostInsert +#if ( $primaryKeys.size() == 1 ) +#set($pKey = $primaryKeys.get(0)) +#if ( $pKey.isColumnNumeric() ) +#set ( $hint = $codewriter.getProperty("generatedkey.statement").replaceAll("
", $tablename) ) +#if ( $genKeyRetrieve == "after" ) + + if (!bean.$strUtil.getModifiedMethod($pKey)()) + { + PreparedStatement ps2 = null; + ResultSet rs = null; + try { + ps2 = c.prepareStatement("$hint"); + rs = ps2.executeQuery(); + if(rs.next()) { + bean.$strUtil.getSetMethod($pKey)($pKey.getResultSetMethodObject("1")); + } else { + log("ATTENTION: Could not retrieve generated key!"); + } + } finally { + close(ps2, rs); + } + } +#elseif ( $genKeyRetrieve == "auto" ) + if (!bean.$strUtil.getModifiedMethod($pKey)() && !delayed) + { + ResultSet rs = ps.getGeneratedKeys(); + try { + if(rs.next()) + bean.$strUtil.getSetMethod($pKey)($pKey.getResultSetMethodObject("1")); + else + log("ATTENTION: Could not retrieve auto generated key!"); + } finally { + close(rs); + } + } +#end +#end +#end +##-------------------/writePostInsert + + bean.isNew(false); + bean.resetIsModified(); + return bean; + } + finally + { + sql = null; + close(ps); + releaseConnection(c); + } + } + + /** + * Update the $beanClass bean record in the database according to the changes. + * + * @param bean the $beanClass bean to be updated + */ + //14 + public $beanClass update($beanClass bean) throws SQLException + { + // mini checks + if (!bean.isModified()) { + return bean; // should not we log something ? + } + if (bean.isNew()){ + return save(bean); + } + + Connection c = null; + PreparedStatement ps = null; + StringBuffer sql = null; + + try + { + c = getConnection(); + +#if ( $primaryKeys.size() == 0 ) +$codewriter.log(" WARN : $tablename does not have any primary key...") +#end +#if ( $isPresentLock ) + $lockColumn.getJavaType() oldLockValue = bean.$strUtil.getGetMethod($lockColumn)(); + bean.$strUtil.getSetMethod($lockColumn))(new $lockColumn.getJavaType()(String.valueOf(System.currentTimeMillis()))); + +#end + sql = new StringBuffer("UPDATE $tablename SET "); + boolean useComma=false; +#foreach( $column in $columns ) + + if (bean.$strUtil.getModifiedMethod($column)()) { + if (useComma) { + sql.append(","); + } else { + useComma=true; + } + sql.append("$column.getName()").append("=?"); + } +#end +#if ( $primaryKeys.size() > 0 ) + sql.append(" WHERE "); +#end +#set ($sql = "" ) +#macro ( sqlAppend $somestr ) +#set ( $sql = "$!sql$somestr" ) +#end +#foreach( $primaryKey in $primaryKeys ) +#if ( $velocityCount > 1 )#sqlAppend( " AND " )#end +#sqlAppend( "$primaryKey.getName()=?" ) +#end +#if ( $isPresentLock ) +#if ( $primaryKeys.size() > 0 )#sqlAppend( " AND " )#end +#sqlAppend( "$lockColumn.getName()=?") +#end + sql.append("$sql"); + if (log.isTraceEnabled()) log.trace("update : " + sql.toString()); + ps = c.prepareStatement(sql.toString(), + ResultSet.TYPE_SCROLL_INSENSITIVE, + ResultSet.CONCUR_READ_ONLY); + + int _dirtyCount = fillPreparedStatement(ps, bean, SEARCH_EXACT); + + if (_dirtyCount == 0) { + if (log.isTraceEnabled()) log.trace("The bean to look is not initialized... do not update."); + return bean; + } + +#foreach ( $pKey in $primaryKeys ) + $pKey.getPreparedStatementMethod("bean.$strUtil.getGetMethod($pKey)()", "++_dirtyCount") +#end +#if ( $isPresentLock ) + $lockColumn.getPreparedStatementMethod( "oldLockValue", "++_dirtyCount") + if (ps.executeUpdate()==0) { + throw new SQLException("sql2java.exception.optimisticlock"); + } +#else + ps.executeUpdate(); +#end + bean.resetIsModified(); + + return bean; + } + finally + { + sql = null; + close(ps); + releaseConnection(c); + } + } + + /** + * Saves an array of $beanClass beans into the database. + * + * @param beans the $beanClass bean table to be saved + * @return the saved $beanClass array. + */ + //15 + public $beanClass[] save($beanClass[] beans) throws SQLException + { + for (int iIndex = 0; iIndex < beans.length; iIndex ++) + { + save(beans[iIndex]); + } + return beans; + } + + /** + * Insert an array of $beanClass beans into the database. + * + * @param beans the $beanClass bean table to be inserted + * @return the saved $beanClass array. + */ + //16 + public $beanClass[] insert($beanClass[] beans) throws SQLException + { + return save(beans); + } + + /** + * Updates an array of $beanClass beans into the database. + * + * @param beans the $beanClass bean table to be inserted + * @return the saved $beanClass array. + */ + //17 + public $beanClass[] update($beanClass[] beans) throws SQLException + { + return save(beans); + } + + + + //_____________________________________________________________________ + // + // USING TEMPLATE + //_____________________________________________________________________ + /** + * Loads a unique $beanClass bean from a template one giving a c + * + * @param bean the $beanClass bean to look for + * @return the bean matching the template + */ + //18 + public $beanClass loadUniqueUsingTemplate($beanClass bean) throws SQLException + { + $beanClass[] beans = loadUsingTemplate(bean); + if (beans.length == 0) + return null; + if (beans.length > 1) + throw new SQLException("More than one element !!"); + return beans[0]; + } + + /** + * Loads an array of $beanClass from a template one. + * + * @param bean the $beanClass template to look for + * @return all the $beanClass matching the template + */ + //19 + public $beanClass[] loadUsingTemplate($beanClass bean) throws SQLException + { + return loadUsingTemplate(bean, 1, -1); + } + + /** + * Loads an array of $beanClass from a template one, given the start row and number of rows. + * + * @param bean the $beanClass template to look for + * @param startRow the start row to be used (first row = 1, last row=-1) + * @param numRows the number of rows to be retrieved (all rows = a negative number) + * @return all the $beanClass matching the template + */ + //20 + public $beanClass[] loadUsingTemplate($beanClass bean, int startRow, int numRows) throws SQLException + { + return loadUsingTemplate(bean, startRow, numRows, SEARCH_EXACT); + } + + /** + * Loads an array of $beanClass from a template one, given the start row and number of rows. + * + * @param bean the $beanClass template to look for + * @param startRow the start row to be used (first row = 1, last row=-1) + * @param numRows the number of rows to be retrieved (all rows = a negative number) + * @param searchType exact ? like ? starting like ? + * @return all the $beanClass matching the template + */ + //20 + public $beanClass[] loadUsingTemplate($beanClass bean, int startRow, int numRows, int searchType) throws SQLException + { + if (log.isTraceEnabled()) log.trace("loadUsingTemplate startRow:" + startRow + ", numRows:" + numRows + ", searchType:" + searchType); + Connection c = null; + PreparedStatement ps = null; + StringBuffer sql = new StringBuffer("SELECT " + ALL_FIELDS + " FROM $tablename "); + StringBuffer sqlWhere = new StringBuffer(""); + + try + { + if (fillWhere(sqlWhere, bean, searchType) == 0) { + if (log.isTraceEnabled()) log.trace("The bean to look is not initialized... loading all"); + } else { + sql.append(" WHERE ").append(sqlWhere); + } + if (log.isTraceEnabled()) log.trace("loadUsingTemplate: " + sql.toString()); + + c = getConnection(); + int scrollType = ResultSet.TYPE_SCROLL_INSENSITIVE; + if (startRow != 1) + scrollType = ResultSet.TYPE_SCROLL_SENSITIVE; + ps = c.prepareStatement(sql.toString(), + scrollType, + ResultSet.CONCUR_READ_ONLY); + fillPreparedStatement(ps, bean, searchType); + + //ps.executeQuery(); + return loadByPreparedStatement(ps, null, startRow, numRows); + } + finally + { + close(ps); + releaseConnection(c); + sql = null; + sqlWhere = null; + } + } + + /** + * Deletes rows using a $beanClass template. + * + * @param bean the $beanClass object(s) to be deleted + * @return the number of deleted objects + */ + //21 + public int deleteUsingTemplate($beanClass bean) throws SQLException + { +#if ( $primaryKeys.size() == 1) + if (bean.$strUtil.getInitializedMethod($primaryKeys.get(0))()) + return deleteByPrimaryKey(bean.$strUtil.getGetMethod($primaryKeys.get(0))()); + +#end + Connection c = null; + PreparedStatement ps = null; + StringBuffer sql = new StringBuffer("DELETE FROM $tablename ");; + StringBuffer sqlWhere = new StringBuffer(""); + + try + { + if (fillWhere(sqlWhere, bean, SEARCH_EXACT) == 0) { + if (log.isTraceEnabled()) log.trace("The bean to look is not initialized... deleting all"); + } else { + sql.append(" WHERE ").append(sqlWhere); + } + if (log.isTraceEnabled()) log.trace("deleteUsingTemplate: " + sql.toString()); + + c = getConnection(); + ps = c.prepareStatement(sql.toString(), + ResultSet.TYPE_SCROLL_INSENSITIVE, + ResultSet.CONCUR_READ_ONLY); + fillPreparedStatement(ps, bean, SEARCH_EXACT); + + int _rows = ps.executeUpdate(); + return _rows; + } + finally + { + close(ps); + releaseConnection(c); + sql = null; + sqlWhere = null; + } + } + + + //_____________________________________________________________________ + // + // COUNT + //_____________________________________________________________________ + + /** + * Retrieves the number of rows of the table $tablename. + * + * @return the number of rows returned + */ + //24 + public int countAll() throws SQLException + { + return countWhere(""); + } + + /** + * Retrieves the number of rows of the table $tablename with a 'where' clause. + * It is up to you to pass the 'WHERE' in your where clausis. + * + * @param where the restriction clause + * @return the number of rows returned + */ + //25 + public int countWhere(String where) throws SQLException + { + String sql = "SELECT COUNT(*) AS MCOUNT FROM $tablename " + where; + if (log.isTraceEnabled()) log.trace("countWhere: " + sql); + Connection c = null; + Statement st = null; + ResultSet rs = null; + try + { + int iReturn = -1; + c = getConnection(); + st = c.createStatement(); + rs = st.executeQuery(sql); + if (rs.next()) + { + iReturn = rs.getInt("MCOUNT"); + } + if (iReturn != -1) + return iReturn; + } + finally + { + close(st, rs); + releaseConnection(c); + sql = null; + } + throw new SQLException("Error in countWhere"); + } + + /** + * Retrieves the number of rows of the table $tablename with a prepared statement. + * + * @param ps the PreparedStatement to be used + * @return the number of rows returned + */ + //26 + int countByPreparedStatement(PreparedStatement ps) throws SQLException + { + ResultSet rs = null; + try + { + int iReturn = -1; + rs = ps.executeQuery(); + if (rs.next()) + iReturn = rs.getInt("MCOUNT"); + if (iReturn != -1) + return iReturn; + } + finally + { + close(rs); + } + throw new SQLException("Error in countByPreparedStatement"); + } + + /** + * count the number of elements of a specific $beanClass bean + * + * @param bean the $beanClass bean to look for ant count + * @return the number of rows returned + */ + //27 + public int countUsingTemplate($beanClass bean) throws SQLException + { + return countUsingTemplate(bean, -1, -1); + } + + /** + * count the number of elements of a specific $beanClass bean , given the start row and number of rows. + * + * @param bean the $beanClass template to look for and count + * @param startRow the start row to be used (first row = 1, last row=-1) + * @param numRows the number of rows to be retrieved (all rows = a negative number) + * @return the number of rows returned + */ + //20 + public int countUsingTemplate($beanClass bean, int startRow, int numRows) throws SQLException + { + return countUsingTemplate(bean, startRow, numRows, SEARCH_EXACT); + } + + /** + * count the number of elements of a specific $beanClass bean given the start row and number of rows and the search type + * + * @param bean the $beanClass template to look for + * @param startRow the start row to be used (first row = 1, last row=-1) + * @param numRows the number of rows to be retrieved (all rows = a negative number) + * @param searchType exact ? like ? starting like ? + * @return the number of rows returned + */ + //20 + public int countUsingTemplate($beanClass bean, int startRow, int numRows, int searchType) throws SQLException + { + Connection c = null; + PreparedStatement ps = null; + StringBuffer sql = new StringBuffer("SELECT COUNT(*) AS MCOUNT FROM $tablename"); + StringBuffer sqlWhere = new StringBuffer(""); + + try + { + if (fillWhere(sqlWhere, bean, SEARCH_EXACT) == 0) { + if (log.isTraceEnabled()) log.trace("The bean to look is not initialized... counting all..."); + } else { + sql.append(" WHERE ").append(sqlWhere); + } + if (log.isTraceEnabled()) log.trace("countUsingTemplate: " + sql.toString()); + + c = getConnection(); + ps = c.prepareStatement(sql.toString(), + ResultSet.TYPE_SCROLL_INSENSITIVE, + ResultSet.CONCUR_READ_ONLY); + fillPreparedStatement(ps, bean, searchType); + + return countByPreparedStatement(ps); + } + finally + { + close(ps); + releaseConnection(c); + sql = null; + sqlWhere = null; + } + } + + // + + + /** + * fills the given stringbuffer with the sql where clausis constructed using the bean and the search type + * @param sqlWhere the stringbuffer that will be filled + * @param bean the bean to use for creating the where clausis + * @param searchType exact ? like ? starting like ? + * @return the number of clausis returned + */ + protected int fillWhere(StringBuffer sqlWhere, $beanClass bean, int searchType) throws SQLException + { + if (bean == null) + return 0; + int _dirtyCount = 0; + StringBuffer sqlEqualsOperation = new StringBuffer("="); + StringBuffer sqlOperation = new StringBuffer("="); + if (searchType != SEARCH_EXACT) + sqlOperation = new StringBuffer(" like "); + try + { +#foreach( $column in $columns ) + if (bean.$strUtil.getModifiedMethod($column)()) { + _dirtyCount ++; +#if ($column.isString()) + sqlWhere.append((sqlWhere.length() == 0) ? " " : " AND ").append("$column.getName() ").append(sqlOperation).append("?"); +#else + sqlWhere.append((sqlWhere.length() == 0) ? " " : " AND ").append("$column.getName() ").append(sqlEqualsOperation).append("?"); +#end + } +#end + } + finally + { + sqlEqualsOperation = null; + sqlOperation = null; + } + return _dirtyCount; + } + + /** + * fill the given prepared statement with the bean values and a search type + * @param ps the preparedStatement that will be filled + * @param bean the bean to use for creating the where clausis + * @param searchType exact ? like ? starting like ? + * @return the number of clausis returned + */ + protected int fillPreparedStatement(PreparedStatement ps, $beanClass bean, int searchType) throws SQLException + { + if (bean == null) + return 0; + int _dirtyCount = 0; +#foreach ( $column in $columns ) + if (bean.$strUtil.getModifiedMethod($column)()) { +#if ($column.isString()) + switch (searchType){ + case SEARCH_EXACT: + if (log.isTraceEnabled()) log.trace("Setting for " + _dirtyCount + " [" + bean.$strUtil.getGetMethod($column)() + "]"); + $column.getPreparedStatementMethod("bean.$strUtil.getGetMethod($column)()", "++_dirtyCount"); + break; + case SEARCH_LIKE: + if (log.isTraceEnabled()) log.trace("Setting for " + _dirtyCount + " [%" + bean.$strUtil.getGetMethod($column)() + "%]"); + $column.getPreparedStatementMethod("${Q}%${Q} + bean.$strUtil.getGetMethod($column)() + ${Q}%${Q}", "++_dirtyCount"); + break; + case SEARCH_STARTING_LIKE: + if (log.isTraceEnabled()) log.trace("Setting for " + _dirtyCount + " [" + bean.$strUtil.getGetMethod($column)() + "%]"); + $column.getPreparedStatementMethod("${Q}%${Q} + bean.$strUtil.getGetMethod($column)()", "++_dirtyCount"); + break; + case SEARCH_ENDING_LIKE: + if (log.isTraceEnabled()) log.trace("Setting for " + _dirtyCount + " [%" + bean.$strUtil.getGetMethod($column)() + "]"); + $column.getPreparedStatementMethod("bean.$strUtil.getGetMethod($column)() + ${Q}%${Q}", "++_dirtyCount"); + break; + } +#else + if (log.isTraceEnabled()) log.trace("Setting for " + _dirtyCount + " [" + bean.$strUtil.getGetMethod($column)() + "]"); + $column.getPreparedStatementMethod("bean.$strUtil.getGetMethod($column)()", "++_dirtyCount"); +#end + } +#end + return _dirtyCount; + } + + + //_____________________________________________________________________ + // + // DECODE RESULT SET + //_____________________________________________________________________ + + /** + * decode a resultset in an array of $beanClass objects + * + * @param rs the resultset to decode + * @param fieldList table of the field's associated constants + * @param startRow the start row to be used (first row = 1, last row = -1) + * @param numRows the number of rows to be retrieved (all rows = a negative number) + * @return the resulting $beanClass table + */ + //28 + public $beanClass[] decodeResultSet(ResultSet rs, int[] fieldList, int startRow, int numRows) throws SQLException + { + java.util.List v = new java.util.ArrayList(); + int count = 0; + try + { + if (rs.absolute(startRow) && numRows!=0) + { + do + { + if(fieldList == null) + v.add(decodeRow(rs)); + else + v.add(decodeRow(rs, fieldList)); + count++; + } while ( (count Date: Wed, 12 Sep 2012 16:13:08 -0700 Subject: [PATCH 03/11] Updated BeanManager with generics. Most XManager code moved to super class. --- README.md | 14 +- src/config/test.properties | 3 +- .../velocity/global/basemanager.java.vm | 467 +++++++++++++++--- .../templates/velocity/global/daobean.java.vm | 5 +- .../velocity/global/daomanager.java.vm | 66 +-- .../templates/velocity/table/bean.java.vm | 28 +- .../templates/velocity/table/manager.java.vm | 330 +------------ 7 files changed, 476 insertions(+), 437 deletions(-) diff --git a/README.md b/README.md index 2c7ba9d..946c008 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,7 @@ This differs from the original project in the following ways: - Uses generics to make the code more concise (and requires Java 1.5) - Not sure if anything but MySQL and HSQL support works anymore. PostgreSQL did work a while ago, but haven't checked in a bit. +### Using: ### To try it out, edit src/config/test.properties to reflect your databases's properties, and run: ./run.sh src/config/test.properties @@ -17,4 +18,15 @@ Which just uses Maven exec:java to run: mvn -e exec:java -Dexec.classpathScope="runtime" -Dexec.mainClass="net.sourceforge.sql2java.Main" -Dexec.args="src/config/test.properties" -Generated classes will appear in target/generated-sources/ or wherever you configured in src/config/test.properties. There is a log at target/velocity.log that will tell you if anything failed, and running Maven with the -e flag should be somewhat informative. \ No newline at end of file +Generated classes will appear in target/generated-sources/ or wherever you configured in src/config/test.properties. There is a log at target/velocity.log that will tell you if anything failed, and running Maven with the -e flag should be somewhat informative. + +### Customizing: ### +The Velocity templates used by the code generator are in src/main/resources/templates/velocity. The per-schema templates are in the global/ subdirectory, and the per-table templates are in the table/ subdirectory. If you add a new template to either directory, you must specify it in your properties file under mgrwriter.templates.perschema or mgrwriter.templates.pertable. + +### Dependencies: ### +- Runtime dependencies for the generated code are slf4j for logging, whatever JDBC driver you need for your database, and google-guava for Immutable Lists/Maps and caching. + +### Feedback: ### +Please submit a pull request if you'd like to see something changed. + +Does anyone else use this? Let me know if you are a user (of this or some sql2java variant). The occasion of meeting users of old/obscure projects that I use has been known to produce free beer in San Francisco. diff --git a/src/config/test.properties b/src/config/test.properties index d164654..0ebc93d 100644 --- a/src/config/test.properties +++ b/src/config/test.properties @@ -86,7 +86,8 @@ mgrwriter.templates.loadingpath=target/classes/templates/velocity/global, \ target/classes/templates/velocity/table, \ target/classes/templates/velocity/includes -mgrwriter.templates.perschema= daomanager.java.vm, \ +mgrwriter.templates.perschema= daobean.java.vm, \ + daomanager.java.vm, \ basemanager.java.vm, \ cachingmanager.java.vm diff --git a/src/main/resources/templates/velocity/global/basemanager.java.vm b/src/main/resources/templates/velocity/global/basemanager.java.vm index 4bf1b3e..55e2fab 100644 --- a/src/main/resources/templates/velocity/global/basemanager.java.vm +++ b/src/main/resources/templates/velocity/global/basemanager.java.vm @@ -9,6 +9,8 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.sql.Types; +import java.util.ArrayList; +import java.util.List; import javax.sql.DataSource; import java.text.SimpleDateFormat; import java.util.Calendar; @@ -18,10 +20,19 @@ import org.slf4j.LoggerFactory; /** * Base data access manager. */ -public abstract class BaseManager implements DaoManager +public abstract class BaseManager implements DaoManager { private static final Logger logger = LoggerFactory.getLogger(BaseManager.class); + /* set =QUERY for loadUsingTemplate */ + static public final int SEARCH_EXACT = 0; + /* set %QUERY% for loadLikeTemplate */ + static public final int SEARCH_LIKE = 1; + /* set %QUERY for loadLikeTemplate */ + static public final int SEARCH_STARTING_LIKE = 2; + /* set QUERY% for loadLikeTemplate */ + static public final int SEARCH_ENDING_LIKE = 3; + protected BaseManager(DataSource dataSource) { this.dataSource = dataSource; } @@ -38,18 +49,80 @@ public abstract class BaseManager implements DaoManager } /** - * Retrieves an array of objects given a sql 'where' clause. + * Creates a new bean instance. * - * @param where The sql 'where' clause - * @return the Resulting object array + * @return the new bean + */ + public abstract T createBean(); + + /** + * Deletes rows according to its keys. + * + * @return the number of deleted rows + */ + public int deleteByPrimaryKey(Integer id) throws SQLException { + throw new UnsupportedOperationException(); + } + + /** + * Loads all the rows from table. + * + * @return an array of beans + */ + public T[] loadAll() throws SQLException { + return loadUsingTemplate(null); + } + + /** + * Loads the given number of rows from table, given the start row. + * + * @param startRow the start row to be used (first row = 1, last row = -1) + * @param numRows the number of rows to be retrieved (all rows = a negative number) + * @return an array of beans + */ + public T[] loadAll(int startRow, int numRows) throws SQLException { + return loadUsingTemplate(null, startRow, numRows); + } + + /** + * Retrieves an array of beans given a sql 'where' clause. + * + * @param where the sql 'where' clause + * @return the resulting bean + */ + public T[] loadByWhere(String where) throws SQLException { + return loadByWhere(where, null); + } + + /** + * Retrieves an array of beans given a sql where clause, and a list of fields. + * It is up to you to pass the 'WHERE' in your where clausis. + * + * @param where the sql 'WHERE' clause + * @param fieldList array of field's ID + * @return the resulting beans */ - public abstract T[] loadByWhere(String where) throws SQLException; + public T[] loadByWhere(String where, int[] fieldList) throws SQLException { + return loadByWhere(where, fieldList, 1, -1); + } + + /** + * Retrieves an array of $beanClass given a sql where clause and a list of fields, and startRow and numRows. + * It is up to you to pass the 'WHERE' in your where clausis. + * + * @param where the sql 'where' clause + * @param startRow the start row to be used (first row = 1, last row = -1) + * @param numRows the number of rows to be retrieved (all rows = a negative number) + * @param fieldList table of the field's associated constants + * @return the resulting $beanClass table + * / + public abstract T[] loadByWhere(String where, int[] fieldList, int startRow, int numRows) throws SQLException; /** * Retrieves the unique object given a sql 'where' clause. * * @param where The sql 'where' clause - * @return The resulting object + * @return The resulting bean */ public T loadUniqueByWhere(String where) throws SQLException { T[] os = loadByWhere(where); @@ -60,45 +133,312 @@ public abstract class BaseManager implements DaoManager } } - // public T createBean(); - // public int deleteByPrimaryKey(Integer id) throws SQLException; - // public T[] loadAll() throws SQLException; - // public T[] loadAll(int startRow, int numRows) throws SQLException; - // public T[] loadByWhere(String where, int[] fieldList) throws SQLException; - // public T[] loadByWhere(String where, int[] fieldList, int startRow, int numRows) throws SQLException; - // public int deleteAll() throws SQLException; - // public int deleteByWhere(String where) throws SQLException; - // public T save(T bean) throws SQLException; - // public T insert(T bean) throws SQLException; - // public T insert(T bean, boolean orUpdate) throws SQLException; - // public T insert(T bean, boolean orUpdate, boolean delayed) throws SQLException; - // public T update(T bean) throws SQLException; - // public T[] save(T[] beans) throws SQLException; - // public T[] insert(T[] beans) throws SQLException; - // public T[] update(T[] beans) throws SQLException; - // public T loadUniqueUsingTemplate(T bean) throws SQLException; - // public T[] loadUsingTemplate(T bean) throws SQLException; - // public T[] loadUsingTemplate(T bean, int startRow, int numRows) throws SQLException; - // public T[] loadUsingTemplate(T bean, int startRow, int numRows, int searchType) throws SQLException; - // public int deleteUsingTemplate(T bean) throws SQLException; - // public int countAll() throws SQLException; - // public int countWhere(String where) throws SQLException; - // public int countUsingTemplate(T bean) throws SQLException; - // public int countUsingTemplate(T bean, int startRow, int numRows) throws SQLException; - // public int countUsingTemplate(T bean, int startRow, int numRows, int searchType) throws SQLException; - // public T[] decodeResultSet(ResultSet rs, int[] fieldList, int startRow, int numRows) throws SQLException; - // public T decodeRow(ResultSet rs) throws SQLException; - // public T decodeRow(ResultSet rs, int[] fieldList) throws SQLException; - // public T metaDataDecodeRow(ResultSet rs) throws SQLException; - // public T[] loadByPreparedStatement(PreparedStatement ps) throws SQLException; - // public T[] loadByPreparedStatement(PreparedStatement ps, int[] fieldList) throws SQLException; - // public T[] loadByPreparedStatement(PreparedStatement ps, int[] fieldList, int startRow, int numRows) throws SQLException; + /** + * Deletes all rows from table. + * @return the number of deleted rows. + */ + public int deleteAll() throws SQLException { + return deleteByWhere(""); + } + + /** + * Deletes rows from the table using a 'where' clause. + * It is up to you to pass the 'WHERE' in your where clausis. + *
Attention, if 'WHERE' is omitted it will delete all records. + * + * @param where the sql 'where' clause + * @return the number of deleted rows + */ + public abstract int deleteByWhere(String where) throws SQLException; + + /** + * Saves the bean into the database. + * + * @param bean the bean to be saved + */ + public T save(T bean) throws SQLException { + if (bean.isNew()) + return insert(bean); + else + return update(bean); + } + + /** + * Insert the bean into the database. + * + * @param bean the bean to be saved + */ + public T insert(T bean) throws SQLException { + return insert(bean, false); + } + + /** + * Insert the bean into the database. + * + * @param bean the bean to be saved + * @param orUpdate on duplicate key update + */ + public T insert(T bean, boolean orUpdate) throws SQLException { + return insert(bean, orUpdate, false); + } + + /** + * Insert the bean into the database. + * + * @param bean the bean to be saved + * @param orUpdate on duplicate key update + * @param delayed use INSERT DELAYED and don't get generated keys + */ + public abstract T insert(T bean, boolean orUpdate, boolean delayed) throws SQLException; + + /** + * Update the $beanClass bean record in the database according to the changes. + * + * @param bean the $beanClass bean to be updated + */ + public abstract T update(T bean) throws SQLException; + + /** + * Saves an array of beans into the database. + * + * @param beans to be saved + * @return the saved bean array. + */ + public T[] save(T[] beans) throws SQLException { + for (int iIndex = 0; iIndex < beans.length; iIndex ++) { + save(beans[iIndex]); + } + return beans; + } + + /** + * Insert an array of beans into the database. + * + * @param beans to be inserted + * @return the saved bean array. + */ + public T[] insert(T[] beans) throws SQLException { + return save(beans); + } + + /** + * Updates an array of beans into the database. + * + * @param beans to be inserted + * @return the saved bean array. + */ + public T[] update(T[] beans) throws SQLException { + return save(beans); + } + + /** + * Loads a unique bean from a template one giving a c + * + * @param bean the bean to look for + * @return the bean matching the template + */ + public T loadUniqueUsingTemplate(T bean) throws SQLException { + T[] beans = loadUsingTemplate(bean); + if (beans.length == 0) + return null; + if (beans.length > 1) + throw new SQLException("More than one element !!"); + return beans[0]; + } + + /** + * Loads an array of from a template one. + * + * @param bean the template to look for + * @return all the matching the template + */ + public T[] loadUsingTemplate(T bean) throws SQLException { + return loadUsingTemplate(bean, 1, -1); + } + + /** + * Loads an array of from a template one, given the start row and number of rows. + * + * @param bean the template to look for + * @param startRow the start row to be used (first row = 1, last row=-1) + * @param numRows the number of rows to be retrieved (all rows = a negative number) + * @return all the matching the template + */ + public T[] loadUsingTemplate(T bean, int startRow, int numRows) throws SQLException { + return loadUsingTemplate(bean, startRow, numRows, SEARCH_EXACT); + } + + /** + * Loads an array of beans from a template one, given the start row and number of rows. + * + * @param bean the bean template to look for + * @param startRow the start row to be used (first row = 1, last row=-1) + * @param numRows the number of rows to be retrieved (all rows = a negative number) + * @param searchType exact ? like ? starting like ? + * @return all the beans matching the template + */ + public abstract T[] loadUsingTemplate(T bean, int startRow, int numRows, int searchType) throws SQLException; + + /** + * Deletes rows using a bean template. + * + * @param bean the bean object(s) to be deleted + * @return the number of deleted objects + */ + public abstract int deleteUsingTemplate(T bean) throws SQLException; + + /** + * Retrieves the number of rows of the table. + * + * @return the number of rows returned + */ + public int countAll() throws SQLException { + return countWhere(""); + } + + /** + * Retrieves the number of rows of the table with a 'where' clause. + * It is up to you to pass the 'WHERE' in your where clause. + * + * @param where the restriction clause + * @return the number of rows returned + */ + public abstract int countWhere(String where) throws SQLException; + + /** + * Count the number of elements of a specific bean + * + * @param bean the bean to look for ant count + * @return the number of rows returned + */ + public int countUsingTemplate(T bean) throws SQLException { + return countUsingTemplate(bean, -1, -1); + } + + /** + * Count the number of elements of a specific bean, given the start row and number of rows. + * + * @param bean the template to look for and count + * @param startRow the start row to be used (first row = 1, last row=-1) + * @param numRows the number of rows to be retrieved (all rows = a negative number) + * @return the number of rows returned + */ + public int countUsingTemplate(T bean, int startRow, int numRows) throws SQLException { + return countUsingTemplate(bean, startRow, numRows, SEARCH_EXACT); + } + + /** + * Count the number of elements of a specific bean given the start row and number of rows and the search type + * + * @param bean the template to look for + * @param startRow the start row to be used (first row = 1, last row=-1) + * @param numRows the number of rows to be retrieved (all rows = a negative number) + * @param searchType exact ? like ? starting like ? + * @return the number of rows returned + */ + public abstract int countUsingTemplate(T bean, int startRow, int numRows, int searchType) throws SQLException; + + /** + * Decode a ResultSet in an array of objects + * + * @param rs the resultset to decode + * @param fieldList table of the field's associated constants + * @param startRow the start row to be used (first row = 1, last row = -1) + * @param numRows the number of rows to be retrieved (all rows = a negative number) + * @return the resulting bean array + */ + public T[] decodeResultSet(ResultSet rs, int[] fieldList, int startRow, int numRows) throws SQLException { + java.util.List v = new java.util.ArrayList(); + int count = 0; + try { + if (rs.absolute(startRow) && numRows!=0) { + do { + if(fieldList == null) + v.add(decodeRow(rs)); + else + v.add(decodeRow(rs, fieldList)); + count++; + } while ( (count implements DaoManager /** * Retrieves an int value from the passed result set as an Integer object. */ - public static Integer getInteger(ResultSet rs, int pos) throws SQLException - { + public static Integer getInteger(ResultSet rs, int pos) throws SQLException { int i = rs.getInt(pos); return rs.wasNull() ? (Integer)null : new Integer(i); } @@ -181,8 +520,7 @@ public abstract class BaseManager implements DaoManager /** * Retrieves an int value from the passed result set as an Integer object. */ - public static Integer getInteger(ResultSet rs, String column) throws SQLException - { + public static Integer getInteger(ResultSet rs, String column) throws SQLException { int i = rs.getInt(column); return rs.wasNull() ? (Integer)null : new Integer(i); } @@ -190,8 +528,7 @@ public abstract class BaseManager implements DaoManager /** * Set an Integer object to the passed prepared statement as an int or as null. */ - public static void setInteger(PreparedStatement ps, int pos, Integer i) throws SQLException - { + public static void setInteger(PreparedStatement ps, int pos, Integer i) throws SQLException { if (i==null) { ps.setNull(pos, Types.INTEGER); @@ -205,8 +542,7 @@ public abstract class BaseManager implements DaoManager /** * Retrieves a float value from the passed result set as a Float object. */ - public static Float getFloat(ResultSet rs, int pos) throws SQLException - { + public static Float getFloat(ResultSet rs, int pos) throws SQLException { float f = rs.getFloat(pos); return rs.wasNull() ? (Float)null : new Float(f); } @@ -214,8 +550,7 @@ public abstract class BaseManager implements DaoManager /** * Retrieves a float value from the passed result set as a Float object. */ - public static Float getFloat(ResultSet rs, String column) throws SQLException - { + public static Float getFloat(ResultSet rs, String column) throws SQLException { float f = rs.getFloat(column); return rs.wasNull() ? (Float)null : new Float(f); } @@ -223,8 +558,7 @@ public abstract class BaseManager implements DaoManager /** * Set a Float object to the passed prepared statement as a float or as null. */ - public static void setFloat(PreparedStatement ps, int pos, Float f) throws SQLException - { + public static void setFloat(PreparedStatement ps, int pos, Float f) throws SQLException { if (f==null) { ps.setNull(pos, Types.FLOAT); @@ -238,8 +572,7 @@ public abstract class BaseManager implements DaoManager /** * Retrieves a double value from the passed result set as a Double object. */ - public static Double getDouble(ResultSet rs, int pos) throws SQLException - { + public static Double getDouble(ResultSet rs, int pos) throws SQLException { double d = rs.getDouble(pos); return rs.wasNull() ? (Double)null : new Double(d); } @@ -247,8 +580,7 @@ public abstract class BaseManager implements DaoManager /** * Retrieves a double value from the passed result set as a Double object. */ - public static Double getDouble(ResultSet rs, String column) throws SQLException - { + public static Double getDouble(ResultSet rs, String column) throws SQLException { double d = rs.getDouble(column); return rs.wasNull() ? (Double)null : new Double(d); } @@ -256,8 +588,7 @@ public abstract class BaseManager implements DaoManager /** * Set a Double object to the passed prepared statement as a double or as null. */ - public static void setDouble(PreparedStatement ps, int pos, Double d) throws SQLException - { + public static void setDouble(PreparedStatement ps, int pos, Double d) throws SQLException { if (d==null) { ps.setNull(pos, Types.DOUBLE); @@ -271,8 +602,7 @@ public abstract class BaseManager implements DaoManager /** * Retrieves a long value from the passed result set as a Long object. */ - public static Long getLong(ResultSet rs, int pos) throws SQLException - { + public static Long getLong(ResultSet rs, int pos) throws SQLException { long l = rs.getLong(pos); return rs.wasNull() ? (Long)null : new Long(l); } @@ -280,8 +610,7 @@ public abstract class BaseManager implements DaoManager /** * Retrieves a long value from the passed result set as a Long object. */ - public static Long getLong(ResultSet rs, String column) throws SQLException - { + public static Long getLong(ResultSet rs, String column) throws SQLException { long l = rs.getLong(column); return rs.wasNull() ? (Long)null : new Long(l); } @@ -289,8 +618,7 @@ public abstract class BaseManager implements DaoManager /** * Set a Long object to the passed prepared statement as a long or as null. */ - public static void setLong(PreparedStatement ps, int pos, Long l) throws SQLException - { + public static void setLong(PreparedStatement ps, int pos, Long l) throws SQLException { if (l==null) { ps.setNull(pos, Types.BIGINT); @@ -304,8 +632,7 @@ public abstract class BaseManager implements DaoManager /** * Retrieves a boolean value from the passed result set as a Boolean object. */ - public static Boolean getBoolean(ResultSet rs, int pos) throws SQLException - { + public static Boolean getBoolean(ResultSet rs, int pos) throws SQLException { boolean b = rs.getBoolean(pos); return rs.wasNull() ? (Boolean)null : new Boolean(b); } @@ -313,8 +640,7 @@ public abstract class BaseManager implements DaoManager /** * Retrieves a boolean value from the passed result set as a Boolean object. */ - public static Boolean getBoolean(ResultSet rs, String column) throws SQLException - { + public static Boolean getBoolean(ResultSet rs, String column) throws SQLException { boolean b = rs.getBoolean(column); return rs.wasNull() ? (Boolean)null : new Boolean(b); } @@ -322,8 +648,7 @@ public abstract class BaseManager implements DaoManager /** * Set a Boolean object to the passed prepared statement as a boolean or as null. */ - public static void setBoolean(PreparedStatement ps, int pos, Boolean b) throws SQLException - { + public static void setBoolean(PreparedStatement ps, int pos, Boolean b) throws SQLException { if (b==null) { ps.setNull(pos, Types.BOOLEAN); diff --git a/src/main/resources/templates/velocity/global/daobean.java.vm b/src/main/resources/templates/velocity/global/daobean.java.vm index 2a5f160..ab2f4ce 100644 --- a/src/main/resources/templates/velocity/global/daobean.java.vm +++ b/src/main/resources/templates/velocity/global/daobean.java.vm @@ -10,6 +10,7 @@ public interface DaoBean public boolean isNew(); public boolean isModified(); public void resetIsModified(); - public Map getDictionnary(); - public Map getPkDictionnary(); + public Map getDictionary(); + public Map getPkDictionary(); + public String toString(String delim); } diff --git a/src/main/resources/templates/velocity/global/daomanager.java.vm b/src/main/resources/templates/velocity/global/daomanager.java.vm index 852ba4c..b78ce8b 100755 --- a/src/main/resources/templates/velocity/global/daomanager.java.vm +++ b/src/main/resources/templates/velocity/global/daomanager.java.vm @@ -12,41 +12,41 @@ import java.sql.SQLException; */ public interface DaoManager { - // public T createBean(); + public T createBean(); public String getTableName(); public T loadByPrimaryKey(Integer id) throws SQLException; - // public int deleteByPrimaryKey(Integer id) throws SQLException; - // public T[] loadAll() throws SQLException; - // public T[] loadAll(int startRow, int numRows) throws SQLException; + public int deleteByPrimaryKey(Integer id) throws SQLException; + public T[] loadAll() throws SQLException; + public T[] loadAll(int startRow, int numRows) throws SQLException; public T[] loadByWhere(String where) throws SQLException; - // public T[] loadByWhere(String where, int[] fieldList) throws SQLException; - // public T[] loadByWhere(String where, int[] fieldList, int startRow, int numRows) throws SQLException; + public T[] loadByWhere(String where, int[] fieldList) throws SQLException; + public T[] loadByWhere(String where, int[] fieldList, int startRow, int numRows) throws SQLException; public T loadUniqueByWhere(String where) throws SQLException; - // public int deleteAll() throws SQLException; - // public int deleteByWhere(String where) throws SQLException; - // public T save(T bean) throws SQLException; - // public T insert(T bean) throws SQLException; - // public T insert(T bean, boolean orUpdate) throws SQLException; - // public T insert(T bean, boolean orUpdate, boolean delayed) throws SQLException; - // public T update(T bean) throws SQLException; - // public T[] save(T[] beans) throws SQLException; - // public T[] insert(T[] beans) throws SQLException; - // public T[] update(T[] beans) throws SQLException; - // public T loadUniqueUsingTemplate(T bean) throws SQLException; - // public T[] loadUsingTemplate(T bean) throws SQLException; - // public T[] loadUsingTemplate(T bean, int startRow, int numRows) throws SQLException; - // public T[] loadUsingTemplate(T bean, int startRow, int numRows, int searchType) throws SQLException; - // public int deleteUsingTemplate(T bean) throws SQLException; - // public int countAll() throws SQLException; - // public int countWhere(String where) throws SQLException; - // public int countUsingTemplate(T bean) throws SQLException; - // public int countUsingTemplate(T bean, int startRow, int numRows) throws SQLException; - // public int countUsingTemplate(T bean, int startRow, int numRows, int searchType) throws SQLException; - // public T[] decodeResultSet(ResultSet rs, int[] fieldList, int startRow, int numRows) throws SQLException; - // public T decodeRow(ResultSet rs) throws SQLException; - // public T decodeRow(ResultSet rs, int[] fieldList) throws SQLException; - // public T metaDataDecodeRow(ResultSet rs) throws SQLException; - // public T[] loadByPreparedStatement(PreparedStatement ps) throws SQLException; - // public T[] loadByPreparedStatement(PreparedStatement ps, int[] fieldList) throws SQLException; - // public T[] loadByPreparedStatement(PreparedStatement ps, int[] fieldList, int startRow, int numRows) throws SQLException; + public int deleteAll() throws SQLException; + public int deleteByWhere(String where) throws SQLException; + public T save(T bean) throws SQLException; + public T insert(T bean) throws SQLException; + public T insert(T bean, boolean orUpdate) throws SQLException; + public T insert(T bean, boolean orUpdate, boolean delayed) throws SQLException; + public T update(T bean) throws SQLException; + public T[] save(T[] beans) throws SQLException; + public T[] insert(T[] beans) throws SQLException; + public T[] update(T[] beans) throws SQLException; + public T loadUniqueUsingTemplate(T bean) throws SQLException; + public T[] loadUsingTemplate(T bean) throws SQLException; + public T[] loadUsingTemplate(T bean, int startRow, int numRows) throws SQLException; + public T[] loadUsingTemplate(T bean, int startRow, int numRows, int searchType) throws SQLException; + public int deleteUsingTemplate(T bean) throws SQLException; + public int countAll() throws SQLException; + public int countWhere(String where) throws SQLException; + public int countUsingTemplate(T bean) throws SQLException; + public int countUsingTemplate(T bean, int startRow, int numRows) throws SQLException; + public int countUsingTemplate(T bean, int startRow, int numRows, int searchType) throws SQLException; + public T[] decodeResultSet(ResultSet rs, int[] fieldList, int startRow, int numRows) throws SQLException; + public T decodeRow(ResultSet rs) throws SQLException; + public T decodeRow(ResultSet rs, int[] fieldList) throws SQLException; + public T metaDataDecodeRow(ResultSet rs) throws SQLException; + public T[] loadByPreparedStatement(PreparedStatement ps) throws SQLException; + public T[] loadByPreparedStatement(PreparedStatement ps, int[] fieldList) throws SQLException; + public T[] loadByPreparedStatement(PreparedStatement ps, int[] fieldList, int startRow, int numRows) throws SQLException; } diff --git a/src/main/resources/templates/velocity/table/bean.java.vm b/src/main/resources/templates/velocity/table/bean.java.vm index c993cfe..3eafb6d 100755 --- a/src/main/resources/templates/velocity/table/bean.java.vm +++ b/src/main/resources/templates/velocity/table/bean.java.vm @@ -23,7 +23,7 @@ public class $beanClass #if ($extendsClass) extends $extendsClass #end - implements Serializable + implements Serializable, DaoBean #if ($implementsClasses) #foreach( $implements in $implementsClasses )$implements#end #end @@ -207,9 +207,19 @@ public class $beanClass */ public String toString() { - return "\n[$tablename] " + return toString("\n"); + } + + /** + * Returns the object string representation. + * @param delim use the provided delimiter between fields. + * @return the object as a string + */ + public String toString(String delim) + { + return "[$tablename] " #foreach ( $column in $columns ) - + "\n - $column.getFullName() = " + ($strUtil.getInitializedVarName($column) ? ("[" + ($strUtil.getVarName($column) == null ? null : ${strUtil.getVarName($column)}.toString()) + "]") : "not initialized") + "" + + delim + " - $column.getFullName() = " + ($strUtil.getInitializedVarName($column) ? ("[" + ($strUtil.getVarName($column) == null ? null : ${strUtil.getVarName($column)}.toString()) + "]") : "not initialized") + "" #end ; } @@ -217,11 +227,11 @@ public class $beanClass /** * return a dictionary of the object */ - public Map getDictionary() + public Map getDictionary() { - Map dictionary = new HashMap(); + Map dictionary = new HashMap(); #foreach ( $column in $columns ) - dictionary.put("$column.getName().toLowerCase()", $strUtil.getGetMethod($column)() == null ? "" : ${strUtil.getGetMethod($column)}().toString()); + dictionary.put("$column.getName().toLowerCase()", ${strUtil.getGetMethod($column)}()); #end return dictionary; } @@ -232,14 +242,14 @@ public class $beanClass * no primary key, the regular dictionary is returned #end */ - public Map getPkDictionary() + public Map getPkDictionary() { #if ( $table.countPrimaryKeys() == 0) return getDictionary(); #else - Map dictionary = new HashMap(); + Map dictionary = new HashMap(); #foreach ( $column in $primaryKeys ) - dictionary.put("$column.getName().toLowerCase()", $strUtil.getGetMethod($column)() == null ? "" : ${strUtil.getGetMethod($column)}().toString()); + dictionary.put("$column.getName().toLowerCase()", ${strUtil.getGetMethod($column)}()); #end return dictionary; #end diff --git a/src/main/resources/templates/velocity/table/manager.java.vm b/src/main/resources/templates/velocity/table/manager.java.vm index c62a8b7..c19009f 100644 --- a/src/main/resources/templates/velocity/table/manager.java.vm +++ b/src/main/resources/templates/velocity/table/manager.java.vm @@ -28,15 +28,6 @@ public class $managerClass extends BaseManager<$beanClass> { private static final Logger log = LoggerFactory.getLogger(${managerClass}.class.getName()); - /* set =QUERY for loadUsingTemplate */ - static public final int SEARCH_EXACT = 0; - /* set %QUERY% for loadLikeTemplate */ - static public final int SEARCH_LIKE = 1; - /* set %QUERY for loadLikeTemplate */ - static public final int SEARCH_STARTING_LIKE = 2; - /* set QUERY% for loadLikeTemplate */ - static public final int SEARCH_ENDING_LIKE = 3; - #foreach ( $column in $columns ) #set ( $vcmo = $velocityCount - 1 ) /** * Identify the $column.getName() field. @@ -98,6 +89,16 @@ public class $managerClass extends BaseManager<$beanClass> return new $beanClass(); } + /** + * Creates a new $beanClass instance. + * + * @return the new $beanClass + */ + public $beanClass createBean() + { + return create$beanClass(); + } + /** * Table managed by this manager * @@ -242,64 +243,9 @@ public class $managerClass extends BaseManager<$beanClass> #end #end - ////////////////////////////////////// - // LOAD ALL - ////////////////////////////////////// - - /** - * Loads all the rows from $tablename. - * - * @return an array of $managerClass bean - */ - //5 - public $beanClass[] loadAll() throws SQLException - { - return loadUsingTemplate(null); - } - - - /** - * Loads the given number of rows from $tablename, given the start row. - * - * @param startRow the start row to be used (first row = 1, last row = -1) - * @param numRows the number of rows to be retrieved (all rows = a negative number) - * @return an array of $managerClass bean - */ - //6 - public $beanClass[] loadAll(int startRow, int numRows) throws SQLException - { - return loadUsingTemplate(null, startRow, numRows); - } - ////////////////////////////////////// // SQL 'WHERE' METHOD ////////////////////////////////////// - /** - * Retrieves an array of $beanClass given a sql 'where' clause. - * - * @param where the sql 'where' clause - * @return the resulting $beanClass table - */ - //7 - public $beanClass[] loadByWhere(String where) throws SQLException - { - return loadByWhere(where, null); - } - - /** - * Retrieves an array of $beanClass given a sql where clause, and a list of fields. - * It is up to you to pass the 'WHERE' in your where clausis. - * - * @param where the sql 'WHERE' clause - * @param fieldList array of field's ID - * @return the resulting $beanClass table - */ - //8 - public $beanClass[] loadByWhere(String where, int[] fieldList) throws SQLException - { - return loadByWhere(where, fieldList, 1, -1); - } - /** * Retrieves an array of $beanClass given a sql where clause and a list of fields, and startRow and numRows. * It is up to you to pass the 'WHERE' in your where clausis. @@ -350,18 +296,6 @@ public class $managerClass extends BaseManager<$beanClass> } } - - /** - * Deletes all rows from $tablename table. - * @return the number of deleted rows. - */ - //10 - public int deleteAll() throws SQLException - { - return deleteByWhere(""); - } - - /** * Deletes rows from the $tablename table using a 'where' clause. * It is up to you to pass the 'WHERE' in your where clausis. @@ -395,44 +329,6 @@ public class $managerClass extends BaseManager<$beanClass> // // SAVE //_____________________________________________________________________ - /** - * Saves the $beanClass bean into the database. - * - * @param bean the $beanClass bean to be saved - */ - //12 - public $beanClass save($beanClass bean) throws SQLException - { - if (bean.isNew()) - return insert(bean); - else - return update(bean); - } - - /** - * Insert the $beanClass bean into the database. - * - * @param bean the $beanClass bean to be saved - */ - //13 - public $beanClass insert($beanClass bean) throws SQLException - { - return insert(bean, false); - } - - /** - * Insert the $beanClass bean into the database. - * - * @param bean the $beanClass bean to be saved - * @param orUpdate on duplicate key update - */ - //13 - public $beanClass insert($beanClass bean, boolean orUpdate) throws SQLException - { - return insert(bean, orUpdate, false); - } - - /** * Insert the $beanClass bean into the database. * @@ -696,45 +592,6 @@ $codewriter.log(" WARN : $tablename does not have any primary key...") } } - /** - * Saves an array of $beanClass beans into the database. - * - * @param beans the $beanClass bean table to be saved - * @return the saved $beanClass array. - */ - //15 - public $beanClass[] save($beanClass[] beans) throws SQLException - { - for (int iIndex = 0; iIndex < beans.length; iIndex ++) - { - save(beans[iIndex]); - } - return beans; - } - - /** - * Insert an array of $beanClass beans into the database. - * - * @param beans the $beanClass bean table to be inserted - * @return the saved $beanClass array. - */ - //16 - public $beanClass[] insert($beanClass[] beans) throws SQLException - { - return save(beans); - } - - /** - * Updates an array of $beanClass beans into the database. - * - * @param beans the $beanClass bean table to be inserted - * @return the saved $beanClass array. - */ - //17 - public $beanClass[] update($beanClass[] beans) throws SQLException - { - return save(beans); - } @@ -742,48 +599,6 @@ $codewriter.log(" WARN : $tablename does not have any primary key...") // // USING TEMPLATE //_____________________________________________________________________ - /** - * Loads a unique $beanClass bean from a template one giving a c - * - * @param bean the $beanClass bean to look for - * @return the bean matching the template - */ - //18 - public $beanClass loadUniqueUsingTemplate($beanClass bean) throws SQLException - { - $beanClass[] beans = loadUsingTemplate(bean); - if (beans.length == 0) - return null; - if (beans.length > 1) - throw new SQLException("More than one element !!"); - return beans[0]; - } - - /** - * Loads an array of $beanClass from a template one. - * - * @param bean the $beanClass template to look for - * @return all the $beanClass matching the template - */ - //19 - public $beanClass[] loadUsingTemplate($beanClass bean) throws SQLException - { - return loadUsingTemplate(bean, 1, -1); - } - - /** - * Loads an array of $beanClass from a template one, given the start row and number of rows. - * - * @param bean the $beanClass template to look for - * @param startRow the start row to be used (first row = 1, last row=-1) - * @param numRows the number of rows to be retrieved (all rows = a negative number) - * @return all the $beanClass matching the template - */ - //20 - public $beanClass[] loadUsingTemplate($beanClass bean, int startRow, int numRows) throws SQLException - { - return loadUsingTemplate(bean, startRow, numRows, SEARCH_EXACT); - } /** * Loads an array of $beanClass from a template one, given the start row and number of rows. @@ -885,17 +700,6 @@ $codewriter.log(" WARN : $tablename does not have any primary key...") // COUNT //_____________________________________________________________________ - /** - * Retrieves the number of rows of the table $tablename. - * - * @return the number of rows returned - */ - //24 - public int countAll() throws SQLException - { - return countWhere(""); - } - /** * Retrieves the number of rows of the table $tablename with a 'where' clause. * It is up to you to pass the 'WHERE' in your where clausis. @@ -959,32 +763,6 @@ $codewriter.log(" WARN : $tablename does not have any primary key...") throw new SQLException("Error in countByPreparedStatement"); } - /** - * count the number of elements of a specific $beanClass bean - * - * @param bean the $beanClass bean to look for ant count - * @return the number of rows returned - */ - //27 - public int countUsingTemplate($beanClass bean) throws SQLException - { - return countUsingTemplate(bean, -1, -1); - } - - /** - * count the number of elements of a specific $beanClass bean , given the start row and number of rows. - * - * @param bean the $beanClass template to look for and count - * @param startRow the start row to be used (first row = 1, last row=-1) - * @param numRows the number of rows to be retrieved (all rows = a negative number) - * @return the number of rows returned - */ - //20 - public int countUsingTemplate($beanClass bean, int startRow, int numRows) throws SQLException - { - return countUsingTemplate(bean, startRow, numRows, SEARCH_EXACT); - } - /** * count the number of elements of a specific $beanClass bean given the start row and number of rows and the search type * @@ -1116,40 +894,6 @@ $codewriter.log(" WARN : $tablename does not have any primary key...") // DECODE RESULT SET //_____________________________________________________________________ - /** - * decode a resultset in an array of $beanClass objects - * - * @param rs the resultset to decode - * @param fieldList table of the field's associated constants - * @param startRow the start row to be used (first row = 1, last row = -1) - * @param numRows the number of rows to be retrieved (all rows = a negative number) - * @return the resulting $beanClass table - */ - //28 - public $beanClass[] decodeResultSet(ResultSet rs, int[] fieldList, int startRow, int numRows) throws SQLException - { - java.util.List v = new java.util.ArrayList(); - int count = 0; - try - { - if (rs.absolute(startRow) && numRows!=0) - { - do - { - if(fieldList == null) - v.add(decodeRow(rs)); - else - v.add(decodeRow(rs, fieldList)); - count++; - } while ( (count Date: Wed, 12 Sep 2012 16:58:00 -0700 Subject: [PATCH 04/11] Switched to List from T[] --- .../velocity/global/basemanager.java.vm | 97 +++++++++---------- .../velocity/global/cachingmanager.java.vm | 9 +- .../velocity/global/daomanager.java.vm | 31 +++--- .../templates/velocity/table/bean.java.vm | 5 +- .../templates/velocity/table/manager.java.vm | 17 ++-- 5 files changed, 80 insertions(+), 79 deletions(-) diff --git a/src/main/resources/templates/velocity/global/basemanager.java.vm b/src/main/resources/templates/velocity/global/basemanager.java.vm index 55e2fab..c197166 100644 --- a/src/main/resources/templates/velocity/global/basemanager.java.vm +++ b/src/main/resources/templates/velocity/global/basemanager.java.vm @@ -10,6 +10,7 @@ import java.sql.SQLException; import java.sql.Statement; import java.sql.Types; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import javax.sql.DataSource; import java.text.SimpleDateFormat; @@ -67,9 +68,9 @@ public abstract class BaseManager implements DaoManager /** * Loads all the rows from table. * - * @return an array of beans + * @return a List of beans */ - public T[] loadAll() throws SQLException { + public List loadAll() throws SQLException { return loadUsingTemplate(null); } @@ -78,36 +79,36 @@ public abstract class BaseManager implements DaoManager * * @param startRow the start row to be used (first row = 1, last row = -1) * @param numRows the number of rows to be retrieved (all rows = a negative number) - * @return an array of beans + * @return a List of beans */ - public T[] loadAll(int startRow, int numRows) throws SQLException { + public List loadAll(int startRow, int numRows) throws SQLException { return loadUsingTemplate(null, startRow, numRows); } /** - * Retrieves an array of beans given a sql 'where' clause. + * Retrieves a List of beans given a sql 'where' clause. * * @param where the sql 'where' clause * @return the resulting bean */ - public T[] loadByWhere(String where) throws SQLException { + public List loadByWhere(String where) throws SQLException { return loadByWhere(where, null); } /** - * Retrieves an array of beans given a sql where clause, and a list of fields. + * Retrieves a List of beans given a sql where clause, and a list of fields. * It is up to you to pass the 'WHERE' in your where clausis. * * @param where the sql 'WHERE' clause * @param fieldList array of field's ID * @return the resulting beans */ - public T[] loadByWhere(String where, int[] fieldList) throws SQLException { + public List loadByWhere(String where, int[] fieldList) throws SQLException { return loadByWhere(where, fieldList, 1, -1); } /** - * Retrieves an array of $beanClass given a sql where clause and a list of fields, and startRow and numRows. + * Retrieves a List of $beanClass given a sql where clause and a list of fields, and startRow and numRows. * It is up to you to pass the 'WHERE' in your where clausis. * * @param where the sql 'where' clause @@ -116,7 +117,7 @@ public abstract class BaseManager implements DaoManager * @param fieldList table of the field's associated constants * @return the resulting $beanClass table * / - public abstract T[] loadByWhere(String where, int[] fieldList, int startRow, int numRows) throws SQLException; + public abstract List loadByWhere(String where, int[] fieldList, int startRow, int numRows) throws SQLException; /** * Retrieves the unique object given a sql 'where' clause. @@ -125,9 +126,9 @@ public abstract class BaseManager implements DaoManager * @return The resulting bean */ public T loadUniqueByWhere(String where) throws SQLException { - T[] os = loadByWhere(where); - if (os != null && os.length > 0) { - return os[0]; + List os = loadByWhere(where); + if (os != null && os.size() > 0) { + return os.get(0); } else { return null; } @@ -199,35 +200,35 @@ public abstract class BaseManager implements DaoManager public abstract T update(T bean) throws SQLException; /** - * Saves an array of beans into the database. + * Saves a List of beans into the database. * * @param beans to be saved - * @return the saved bean array. + * @return the saved bean List. */ - public T[] save(T[] beans) throws SQLException { - for (int iIndex = 0; iIndex < beans.length; iIndex ++) { - save(beans[iIndex]); + public List save(List beans) throws SQLException { + for (T bean:beans) { + save(bean); } return beans; } /** - * Insert an array of beans into the database. + * Insert a List of beans into the database. * * @param beans to be inserted - * @return the saved bean array. + * @return the saved bean List. */ - public T[] insert(T[] beans) throws SQLException { + public List insert(List beans) throws SQLException { return save(beans); } /** - * Updates an array of beans into the database. + * Updates an List of beans into the database. * * @param beans to be inserted - * @return the saved bean array. + * @return the saved bean List. */ - public T[] update(T[] beans) throws SQLException { + public List update(List beans) throws SQLException { return save(beans); } @@ -238,38 +239,38 @@ public abstract class BaseManager implements DaoManager * @return the bean matching the template */ public T loadUniqueUsingTemplate(T bean) throws SQLException { - T[] beans = loadUsingTemplate(bean); - if (beans.length == 0) + List beans = loadUsingTemplate(bean); + if (beans.size() == 0) return null; - if (beans.length > 1) + if (beans.size() > 1) throw new SQLException("More than one element !!"); - return beans[0]; + return beans.get(0); } /** - * Loads an array of from a template one. + * Loads a List of from a template one. * * @param bean the template to look for * @return all the matching the template */ - public T[] loadUsingTemplate(T bean) throws SQLException { + public List loadUsingTemplate(T bean) throws SQLException { return loadUsingTemplate(bean, 1, -1); } /** - * Loads an array of from a template one, given the start row and number of rows. + * Loads a List of from a template one, given the start row and number of rows. * * @param bean the template to look for * @param startRow the start row to be used (first row = 1, last row=-1) * @param numRows the number of rows to be retrieved (all rows = a negative number) * @return all the matching the template */ - public T[] loadUsingTemplate(T bean, int startRow, int numRows) throws SQLException { + public List loadUsingTemplate(T bean, int startRow, int numRows) throws SQLException { return loadUsingTemplate(bean, startRow, numRows, SEARCH_EXACT); } /** - * Loads an array of beans from a template one, given the start row and number of rows. + * Loads a List of beans from a template one, given the start row and number of rows. * * @param bean the bean template to look for * @param startRow the start row to be used (first row = 1, last row=-1) @@ -277,7 +278,7 @@ public abstract class BaseManager implements DaoManager * @param searchType exact ? like ? starting like ? * @return all the beans matching the template */ - public abstract T[] loadUsingTemplate(T bean, int startRow, int numRows, int searchType) throws SQLException; + public abstract List loadUsingTemplate(T bean, int startRow, int numRows, int searchType) throws SQLException; /** * Deletes rows using a bean template. @@ -339,28 +340,26 @@ public abstract class BaseManager implements DaoManager public abstract int countUsingTemplate(T bean, int startRow, int numRows, int searchType) throws SQLException; /** - * Decode a ResultSet in an array of objects + * Decode a ResultSet in a List of objects * * @param rs the resultset to decode * @param fieldList table of the field's associated constants * @param startRow the start row to be used (first row = 1, last row = -1) * @param numRows the number of rows to be retrieved (all rows = a negative number) - * @return the resulting bean array + * @return the resulting bean List */ - public T[] decodeResultSet(ResultSet rs, int[] fieldList, int startRow, int numRows) throws SQLException { - java.util.List v = new java.util.ArrayList(); + public List decodeResultSet(ResultSet rs, int[] fieldList, int startRow, int numRows) throws SQLException { + List v = new ArrayList(); int count = 0; try { if (rs.absolute(startRow) && numRows!=0) { do { - if(fieldList == null) - v.add(decodeRow(rs)); - else - v.add(decodeRow(rs, fieldList)); + if(fieldList == null) v.add(decodeRow(rs)); + else v.add(decodeRow(rs, fieldList)); count++; } while ( (count implements DaoManager * Loads all the elements using a prepared statement. * * @param ps the PreparedStatement to be used - * @return an array of beans + * @return a List of beans */ - public T[] loadByPreparedStatement(PreparedStatement ps) throws SQLException { + public List loadByPreparedStatement(PreparedStatement ps) throws SQLException { return loadByPreparedStatement(ps, null); } @@ -406,9 +405,9 @@ public abstract class BaseManager implements DaoManager * * @param ps the PreparedStatement to be used * @param fieldList table of the field's associated constants - * @return an array of beans + * @return a List of beans */ - public T[] loadByPreparedStatement(PreparedStatement ps, int[] fieldList) throws SQLException { + public List loadByPreparedStatement(PreparedStatement ps, int[] fieldList) throws SQLException { return loadByPreparedStatement(ps, fieldList, 1, -1); } @@ -420,9 +419,9 @@ public abstract class BaseManager implements DaoManager * @param startRow the start row to be used (first row = 1, last row = -1) * @param numRows the number of rows to be retrieved (all rows = a negative number) * @param fieldList table of the field's associated constants - * @return an array of beans + * @return a List of beans */ - public T[] loadByPreparedStatement(PreparedStatement ps, int[] fieldList, int startRow, int numRows) throws SQLException { + public List loadByPreparedStatement(PreparedStatement ps, int[] fieldList, int startRow, int numRows) throws SQLException { ResultSet rs = null; try { rs = ps.executeQuery(); diff --git a/src/main/resources/templates/velocity/global/cachingmanager.java.vm b/src/main/resources/templates/velocity/global/cachingmanager.java.vm index 8b21ab1..d338a78 100755 --- a/src/main/resources/templates/velocity/global/cachingmanager.java.vm +++ b/src/main/resources/templates/velocity/global/cachingmanager.java.vm @@ -4,6 +4,7 @@ $codewriter.setCurrentJavaFilename($pkg, "CachingManager.java") package $pkg; import java.util.HashMap; +import java.util.List; import java.util.Map; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -72,16 +73,16 @@ public class CachingManager * @param where The WHERE clause. * @return The bean or null. */ - public T[] get(String where) + public List get(String where) { CacheEntry entry = (CacheEntry)cache.get(where); - if (entry != null && entry.valid()) return (T[])entry.getBean(); + if (entry != null && entry.valid()) return (List)entry.getBean(); try { - Object[] o = manager.loadByWhere(where); + List o = manager.loadByWhere(where); if (o != null) { logger.trace("CACHE PUT: "+where); cache.put(where, new CacheEntry(where, o, expiration)); - return (T[])o; + return o; } } catch (Exception e) { logger.error("Error loading bean from cache: ", e); diff --git a/src/main/resources/templates/velocity/global/daomanager.java.vm b/src/main/resources/templates/velocity/global/daomanager.java.vm index b78ce8b..c602764 100755 --- a/src/main/resources/templates/velocity/global/daomanager.java.vm +++ b/src/main/resources/templates/velocity/global/daomanager.java.vm @@ -6,6 +6,7 @@ package $pkg; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; +import java.util.List; /** * Data access manager. @@ -16,11 +17,11 @@ public interface DaoManager public String getTableName(); public T loadByPrimaryKey(Integer id) throws SQLException; public int deleteByPrimaryKey(Integer id) throws SQLException; - public T[] loadAll() throws SQLException; - public T[] loadAll(int startRow, int numRows) throws SQLException; - public T[] loadByWhere(String where) throws SQLException; - public T[] loadByWhere(String where, int[] fieldList) throws SQLException; - public T[] loadByWhere(String where, int[] fieldList, int startRow, int numRows) throws SQLException; + public List loadAll() throws SQLException; + public List loadAll(int startRow, int numRows) throws SQLException; + public List loadByWhere(String where) throws SQLException; + public List loadByWhere(String where, int[] fieldList) throws SQLException; + public List loadByWhere(String where, int[] fieldList, int startRow, int numRows) throws SQLException; public T loadUniqueByWhere(String where) throws SQLException; public int deleteAll() throws SQLException; public int deleteByWhere(String where) throws SQLException; @@ -29,24 +30,24 @@ public interface DaoManager public T insert(T bean, boolean orUpdate) throws SQLException; public T insert(T bean, boolean orUpdate, boolean delayed) throws SQLException; public T update(T bean) throws SQLException; - public T[] save(T[] beans) throws SQLException; - public T[] insert(T[] beans) throws SQLException; - public T[] update(T[] beans) throws SQLException; + public List save(List beans) throws SQLException; + public List insert(List beans) throws SQLException; + public List update(List beans) throws SQLException; public T loadUniqueUsingTemplate(T bean) throws SQLException; - public T[] loadUsingTemplate(T bean) throws SQLException; - public T[] loadUsingTemplate(T bean, int startRow, int numRows) throws SQLException; - public T[] loadUsingTemplate(T bean, int startRow, int numRows, int searchType) throws SQLException; + public List loadUsingTemplate(T bean) throws SQLException; + public List loadUsingTemplate(T bean, int startRow, int numRows) throws SQLException; + public List loadUsingTemplate(T bean, int startRow, int numRows, int searchType) throws SQLException; public int deleteUsingTemplate(T bean) throws SQLException; public int countAll() throws SQLException; public int countWhere(String where) throws SQLException; public int countUsingTemplate(T bean) throws SQLException; public int countUsingTemplate(T bean, int startRow, int numRows) throws SQLException; public int countUsingTemplate(T bean, int startRow, int numRows, int searchType) throws SQLException; - public T[] decodeResultSet(ResultSet rs, int[] fieldList, int startRow, int numRows) throws SQLException; + public List decodeResultSet(ResultSet rs, int[] fieldList, int startRow, int numRows) throws SQLException; public T decodeRow(ResultSet rs) throws SQLException; public T decodeRow(ResultSet rs, int[] fieldList) throws SQLException; public T metaDataDecodeRow(ResultSet rs) throws SQLException; - public T[] loadByPreparedStatement(PreparedStatement ps) throws SQLException; - public T[] loadByPreparedStatement(PreparedStatement ps, int[] fieldList) throws SQLException; - public T[] loadByPreparedStatement(PreparedStatement ps, int[] fieldList, int startRow, int numRows) throws SQLException; + public List loadByPreparedStatement(PreparedStatement ps) throws SQLException; + public List loadByPreparedStatement(PreparedStatement ps, int[] fieldList) throws SQLException; + public List loadByPreparedStatement(PreparedStatement ps, int[] fieldList, int startRow, int numRows) throws SQLException; } diff --git a/src/main/resources/templates/velocity/table/bean.java.vm b/src/main/resources/templates/velocity/table/bean.java.vm index 3eafb6d..024c846 100755 --- a/src/main/resources/templates/velocity/table/bean.java.vm +++ b/src/main/resources/templates/velocity/table/bean.java.vm @@ -7,6 +7,7 @@ package $table.getPackage(); import $pkg.*; import java.io.Serializable; +import java.util.Collections; import java.util.Map; import java.util.HashMap; @@ -233,7 +234,7 @@ public class $beanClass #foreach ( $column in $columns ) dictionary.put("$column.getName().toLowerCase()", ${strUtil.getGetMethod($column)}()); #end - return dictionary; + return Collections.unmodifiableMap(dictionary); } /** @@ -251,7 +252,7 @@ public class $beanClass #foreach ( $column in $primaryKeys ) dictionary.put("$column.getName().toLowerCase()", ${strUtil.getGetMethod($column)}()); #end - return dictionary; + return Collections.unmodifiableMap(dictionary); #end } } diff --git a/src/main/resources/templates/velocity/table/manager.java.vm b/src/main/resources/templates/velocity/table/manager.java.vm index c19009f..14cb628 100644 --- a/src/main/resources/templates/velocity/table/manager.java.vm +++ b/src/main/resources/templates/velocity/table/manager.java.vm @@ -10,6 +10,7 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.sql.Types; +import java.util.List; import javax.sql.DataSource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -147,11 +148,11 @@ public class $managerClass extends BaseManager<$beanClass> #foreach( $pk in $primaryKeys ) $pk.getPreparedStatementMethod($strUtil.getVarName($pk), $velocityCount) #end - $beanClass pReturn[] = loadByPreparedStatement(ps); - if (pReturn.length < 1) + List<$beanClass> pReturn = loadByPreparedStatement(ps); + if (pReturn.size() < 1) return null; else - return pReturn[0]; + return pReturn.get(0); } finally { @@ -247,7 +248,7 @@ public class $managerClass extends BaseManager<$beanClass> // SQL 'WHERE' METHOD ////////////////////////////////////// /** - * Retrieves an array of $beanClass given a sql where clause and a list of fields, and startRow and numRows. + * Retrieves a List of $beanClass given a sql where clause and a list of fields, and startRow and numRows. * It is up to you to pass the 'WHERE' in your where clausis. * * @param where the sql 'where' clause @@ -257,7 +258,7 @@ public class $managerClass extends BaseManager<$beanClass> * @return the resulting $beanClass table */ //9 - public $beanClass[] loadByWhere(String where, int[] fieldList, int startRow, int numRows) throws SQLException + public List<$beanClass> loadByWhere(String where, int[] fieldList, int startRow, int numRows) throws SQLException { String sql = null; if(fieldList == null) @@ -593,15 +594,13 @@ $codewriter.log(" WARN : $tablename does not have any primary key...") } - - //_____________________________________________________________________ // // USING TEMPLATE //_____________________________________________________________________ /** - * Loads an array of $beanClass from a template one, given the start row and number of rows. + * Loads a List of $beanClass from a template one, given the start row and number of rows. * * @param bean the $beanClass template to look for * @param startRow the start row to be used (first row = 1, last row=-1) @@ -610,7 +609,7 @@ $codewriter.log(" WARN : $tablename does not have any primary key...") * @return all the $beanClass matching the template */ //20 - public $beanClass[] loadUsingTemplate($beanClass bean, int startRow, int numRows, int searchType) throws SQLException + public List<$beanClass> loadUsingTemplate($beanClass bean, int startRow, int numRows, int searchType) throws SQLException { if (log.isTraceEnabled()) log.trace("loadUsingTemplate startRow:" + startRow + ", numRows:" + numRows + ", searchType:" + searchType); Connection c = null; From e09487ecea047ff1ec2a15ea131295d290934d36 Mon Sep 17 00:00:00 2001 From: garthpatil Date: Tue, 18 Sep 2012 11:12:20 -0700 Subject: [PATCH 05/11] added listener and base listener --- src/config/test.properties | 2 + .../java/net/sourceforge/sql2java/Main.java | 1 - .../velocity/global/baselistener.java.vm | 71 ++++ .../velocity/global/basemanager.java.vm | 388 +++++++++++++++--- .../velocity/global/listener.java.vm | 55 +++ .../templates/velocity/table/listener.java.vm | 47 --- .../templates/velocity/table/manager.java.vm | 334 +++------------ 7 files changed, 498 insertions(+), 400 deletions(-) create mode 100644 src/main/resources/templates/velocity/global/baselistener.java.vm create mode 100755 src/main/resources/templates/velocity/global/listener.java.vm delete mode 100755 src/main/resources/templates/velocity/table/listener.java.vm diff --git a/src/config/test.properties b/src/config/test.properties index 0ebc93d..c99697b 100644 --- a/src/config/test.properties +++ b/src/config/test.properties @@ -89,6 +89,8 @@ mgrwriter.templates.loadingpath=target/classes/templates/velocity/global, \ mgrwriter.templates.perschema= daobean.java.vm, \ daomanager.java.vm, \ basemanager.java.vm, \ + listener.java.vm, \ + baselistener.java.vm, \ cachingmanager.java.vm mgrwriter.templates.pertable= bean.java.vm, \ diff --git a/src/main/java/net/sourceforge/sql2java/Main.java b/src/main/java/net/sourceforge/sql2java/Main.java index 576ae3d..6b59196 100755 --- a/src/main/java/net/sourceforge/sql2java/Main.java +++ b/src/main/java/net/sourceforge/sql2java/Main.java @@ -46,7 +46,6 @@ public static void main(String argv[], Map overideFileProperties) db.setSchema(getProperty("jdbc.schema")); db.setTableNamePattern(getProperty("jdbc.tablenamepattern")); - if (overideFileProperties != null) prop.putAll(overideFileProperties); diff --git a/src/main/resources/templates/velocity/global/baselistener.java.vm b/src/main/resources/templates/velocity/global/baselistener.java.vm new file mode 100644 index 0000000..de0c58a --- /dev/null +++ b/src/main/resources/templates/velocity/global/baselistener.java.vm @@ -0,0 +1,71 @@ +##$Id: listener.java.vm,v 1.1 2005/10/12 12:37:58 framiere Exp $ +#parse( "header.include.vm" ) +$codewriter.setCurrentJavaFilename($pkg, "BaseListener.java") +package $pkg; + +import $pkg.*; + +/** + * No-op implementation of Listener as a convenience for implementing classes. + */ +public abstract class BaseListener implements Listener +{ + /** + * Invoked just before inserting a record into the database. + * + * @param bean the bean that is about to be inserted + */ + public void beforeInsert(T bean) { + + } + + /** + * Invoked just after a record is inserted in the database. + * + * @param bean the bean that was just inserted + */ + public void afterInsert(T bean) { + + } + + + /** + * Invoked just before updating a record in the database. + * + * @param bean the bean that is about to be updated + */ + public void beforeUpdate(T bean) { + + } + + + /** + * Invoked just after updating a record in the database. + * + * @param bean the bean that was just updated + */ + public void afterUpdate(T bean) { + + } + + + /** + * Invoked just before deleting a record in the database. + * + * @param bean the bean that is about to be deleted + */ + public void beforeDelete(T bean) { + + } + + + /** + * Invoked just after deleting a record in the database. + * + * @param bean the bean that was just deleted + */ + public void afterDelete(T bean) { + + } + +} diff --git a/src/main/resources/templates/velocity/global/basemanager.java.vm b/src/main/resources/templates/velocity/global/basemanager.java.vm index c197166..502ad02 100644 --- a/src/main/resources/templates/velocity/global/basemanager.java.vm +++ b/src/main/resources/templates/velocity/global/basemanager.java.vm @@ -23,7 +23,7 @@ import org.slf4j.LoggerFactory; */ public abstract class BaseManager implements DaoManager { - private static final Logger logger = LoggerFactory.getLogger(BaseManager.class); + private static final Logger log = LoggerFactory.getLogger(BaseManager.class); /* set =QUERY for loadUsingTemplate */ static public final int SEARCH_EXACT = 0; @@ -39,6 +39,34 @@ public abstract class BaseManager implements DaoManager } protected DataSource dataSource; + protected Listener listener; + + /** + * Contains all the full fields of the table. + */ + protected abstract String[] getFullFieldNames(); + + /** + * Contains all the fields of the table. + */ + protected abstract String[] getFieldNames(); + + /** + * Field that contains the comma separated fields of the table. + */ + protected abstract String getAllFullFields(); + + /** + * Field that contains the comma separated fields of the table. + */ + protected abstract String getAllFields(); + + /** + * Set the listener for INSERT/UPDATE/DELETE operations. + */ + public void setListener(Listener listener) { + this.listener = listener; + } /** * Loads an object from the table using its key field. @@ -56,6 +84,13 @@ public abstract class BaseManager implements DaoManager */ public abstract T createBean(); + /** + * Table managed by this manager + * + * @return tablename + */ + public abstract String getTableName(); + /** * Deletes rows according to its keys. * @@ -108,16 +143,47 @@ public abstract class BaseManager implements DaoManager } /** - * Retrieves a List of $beanClass given a sql where clause and a list of fields, and startRow and numRows. + * Retrieves a List of beans given a sql where clause and a list of fields, and startRow and numRows. * It is up to you to pass the 'WHERE' in your where clausis. * * @param where the sql 'where' clause * @param startRow the start row to be used (first row = 1, last row = -1) * @param numRows the number of rows to be retrieved (all rows = a negative number) * @param fieldList table of the field's associated constants - * @return the resulting $beanClass table - * / - public abstract List loadByWhere(String where, int[] fieldList, int startRow, int numRows) throws SQLException; + * @return the resulting bean List + */ + public List loadByWhere(String where, int[] fieldList, int startRow, int numRows) throws SQLException + { + String sql = null; + if (fieldList == null) { + sql = "SELECT " + getAllFields() + " FROM " + getTableName() + " " + where; + } else { + StringBuilder buff = new StringBuilder(); + buff.append("SELECT "); + for(int i = 0; i < fieldList.length; i++) { + if(i != 0) buff.append(","); + buff.append(getFieldNames()[fieldList[i]]); + } + buff.append(" FROM " + getTableName() + " "); + buff.append(where); + sql = buff.toString(); + buff = null; + } + Connection c = null; + Statement st = null; + ResultSet rs = null; + if (log.isTraceEnabled()) log.trace("loadByWhere: {}", sql); + try { + c = getConnection(); + st = c.createStatement(); + rs = st.executeQuery(sql); + return decodeResultSet(rs, fieldList, startRow, numRows); + } finally { + sql = null; + close(st, rs); + releaseConnection(c); + } + } /** * Retrieves the unique object given a sql 'where' clause. @@ -150,7 +216,21 @@ public abstract class BaseManager implements DaoManager * @param where the sql 'where' clause * @return the number of deleted rows */ - public abstract int deleteByWhere(String where) throws SQLException; + public int deleteByWhere(String where) throws SQLException + { + Connection c = null; + PreparedStatement ps = null; + try { + c = getConnection(); + StringBuilder sql = new StringBuilder("DELETE FROM " + getTableName() + " " + where); + if (log.isTraceEnabled()) log.trace("deleteByWhere: {}", sql); + ps = c.prepareStatement(sql.toString()); + return ps.executeUpdate(); + } finally { + close(ps); + releaseConnection(c); + } + } /** * Saves the bean into the database. @@ -193,9 +273,9 @@ public abstract class BaseManager implements DaoManager public abstract T insert(T bean, boolean orUpdate, boolean delayed) throws SQLException; /** - * Update the $beanClass bean record in the database according to the changes. + * Update the bean record in the database according to the changes. * - * @param bean the $beanClass bean to be updated + * @param bean the bean to be updated */ public abstract T update(T bean) throws SQLException; @@ -278,7 +358,35 @@ public abstract class BaseManager implements DaoManager * @param searchType exact ? like ? starting like ? * @return all the beans matching the template */ - public abstract List loadUsingTemplate(T bean, int startRow, int numRows, int searchType) throws SQLException; + public List loadUsingTemplate(T bean, int startRow, int numRows, int searchType) throws SQLException { + if (log.isTraceEnabled()) log.trace("loadUsingTemplate startRow:{}, numRows:{}, searchType:{}", new Object[] { startRow, numRows, searchType }); + Connection c = null; + PreparedStatement ps = null; + StringBuilder sql = new StringBuilder("SELECT " + getAllFields() + " FROM " + getTableName() + " "); + StringBuilder sqlWhere = new StringBuilder(""); + + try { + if (fillWhere(sqlWhere, bean, searchType) == 0) { + if (log.isTraceEnabled()) log.trace("The bean to look is not initialized... loading all"); + } else { + sql.append(" WHERE ").append(sqlWhere); + } + if (log.isTraceEnabled()) log.trace("loadUsingTemplate: {}", sql); + c = getConnection(); + int scrollType = ResultSet.TYPE_SCROLL_INSENSITIVE; + if (startRow != 1) scrollType = ResultSet.TYPE_SCROLL_SENSITIVE; + ps = c.prepareStatement(sql.toString(), + scrollType, + ResultSet.CONCUR_READ_ONLY); + fillPreparedStatement(ps, bean, searchType); + return loadByPreparedStatement(ps, null, startRow, numRows); + } finally { + close(ps); + releaseConnection(c); + sql = null; + sqlWhere = null; + } + } /** * Deletes rows using a bean template. @@ -304,7 +412,31 @@ public abstract class BaseManager implements DaoManager * @param where the restriction clause * @return the number of rows returned */ - public abstract int countWhere(String where) throws SQLException; + public int countWhere(String where) throws SQLException + { + String sql = "SELECT COUNT(*) AS MCOUNT FROM " + getTableName() + " " + where; + if (log.isTraceEnabled()) log.trace("countWhere: {}", sql); + Connection c = null; + Statement st = null; + ResultSet rs = null; + try { + int iReturn = -1; + c = getConnection(); + st = c.createStatement(); + rs = st.executeQuery(sql); + if (rs.next()) { + iReturn = rs.getInt("MCOUNT"); + } + if (iReturn != -1) + return iReturn; + } finally { + close(st, rs); + releaseConnection(c); + sql = null; + } + throw new SQLException("Error in countWhere"); + } + /** * Count the number of elements of a specific bean @@ -337,7 +469,50 @@ public abstract class BaseManager implements DaoManager * @param searchType exact ? like ? starting like ? * @return the number of rows returned */ - public abstract int countUsingTemplate(T bean, int startRow, int numRows, int searchType) throws SQLException; + public int countUsingTemplate(T bean, int startRow, int numRows, int searchType) throws SQLException { + Connection c = null; + PreparedStatement ps = null; + StringBuilder sql = new StringBuilder("SELECT COUNT(*) AS MCOUNT FROM " + getTableName()); + StringBuilder sqlWhere = new StringBuilder(""); + try { + if (fillWhere(sqlWhere, bean, SEARCH_EXACT) == 0) { + if (log.isTraceEnabled()) log.trace("The bean to look is not initialized... counting all..."); + } else { + sql.append(" WHERE ").append(sqlWhere); + } + if (log.isTraceEnabled()) log.trace("countUsingTemplate: {}", sql); + c = getConnection(); + ps = c.prepareStatement(sql.toString(), + ResultSet.TYPE_SCROLL_INSENSITIVE, + ResultSet.CONCUR_READ_ONLY); + fillPreparedStatement(ps, bean, searchType); + return countByPreparedStatement(ps); + } finally { + close(ps); + releaseConnection(c); + sql = null; + sqlWhere = null; + } + } + + /** + * Retrieves the number of rows of the table with a prepared statement. + * + * @param ps the PreparedStatement to be used + * @return the number of rows returned + */ + protected int countByPreparedStatement(PreparedStatement ps) throws SQLException { + ResultSet rs = null; + try { + int iReturn = -1; + rs = ps.executeQuery(); + if (rs.next()) iReturn = rs.getInt("MCOUNT"); + if (iReturn != -1) return iReturn; + } finally { + close(rs); + } + throw new SQLException("Error in countByPreparedStatement"); + } /** * Decode a ResultSet in a List of objects @@ -431,9 +606,112 @@ public abstract class BaseManager implements DaoManager } } + /** + * fills the given stringbuffer with the sql where clausis constructed using the bean and the search type + * @param sqlWhere the stringbuffer that will be filled + * @param bean the bean to use for creating the where clausis + * @param searchType exact ? like ? starting like ? + * @return the number of clausis returned + */ + protected abstract int fillWhere(StringBuilder sqlWhere, T bean, int searchType) throws SQLException; + + /** + * fill the given prepared statement with the bean values and a search type + * @param ps the preparedStatement that will be filled + * @param bean the bean to use for creating the where clausis + * @param searchType exact ? like ? starting like ? + * @return the number of clausis returned + */ + protected abstract int fillPreparedStatement(PreparedStatement ps, T bean, int searchType) throws SQLException; + // UTILITIES + + /** + * Notify Listener before INSERT, suppressing exceptions from the Listener + * @param bean the bean before INSERT + */ + protected void beforeInsert(T bean) { + if (listener != null) { + try { + listener.beforeInsert(bean); + } catch (Exception e) { + log.trace("Error notifying listener.beforeInsert: {}", e); + } + } + } + + /** + * Notify Listener after INSERT, suppressing exceptions from the Listener + * @param bean the bean after INSERT + */ + protected void afterInsert(T bean) { + if (listener != null) { + try { + listener.afterInsert(bean); + } catch (Exception e) { + log.trace("Error notifying listener.afterInsert: {}", e); + } + } + } + + /** + * Notify Listener before UPDATE, suppressing exceptions from the Listener + * @param bean the bean before UPDATE + */ + protected void beforeUpdate(T bean) { + if (listener != null) { + try { + listener.beforeUpdate(bean); + } catch (Exception e) { + log.trace("Error notifying listener.beforeUpdate: {}", e); + } + } + } + + /** + * Notify Listener after UPDATE, suppressing exceptions from the Listener + * @param bean the bean after UPDATE + */ + protected void afterUpdate(T bean) { + if (listener != null) { + try { + listener.afterUpdate(bean); + } catch (Exception e) { + log.trace("Error notifying listener.afterUpdate: {}", e); + } + } + } + + /** + * Notify Listener before DELETE, suppressing exceptions from the Listener + * @param bean the bean before DELETE + */ + protected void beforeDelete(T bean) { + if (listener != null) { + try { + listener.beforeDelete(bean); + } catch (Exception e) { + log.trace("Error notifying listener.beforeDelete: {}", e); + } + } + } + + /** + * Notify Listener after DELETE, suppressing exceptions from the Listener + * @param bean the bean after DELETE + */ + protected void afterDelete(T bean) { + if (listener != null) { + try { + listener.afterDelete(bean); + } catch (Exception e) { + log.trace("Error notifying listener.afterDelete: {}", e); + } + } + } + /** * @return an auto commit connection */ @@ -450,32 +728,20 @@ public abstract class BaseManager implements DaoManager try { c.close(); } catch (Exception e) { - logger.warn("Error releasing connection.", e); + log.warn("Error releasing connection", e); } } } - /** - * Logs a message using the underlying logwriter, if not null. - */ - public void log(String message) - { - if (logger.isTraceEnabled()) logger.trace(message); - } - /** * Closes the passed Statement. */ public void close(Statement s) { - try - { - if (s != null) - s.close(); - } - catch (SQLException x) - { - log("Could not close statement!: " + x.toString()); + try { + if (s != null) s.close(); + } catch (SQLException x) { + log.warn("Could not close statement", x); } } @@ -484,14 +750,10 @@ public abstract class BaseManager implements DaoManager */ public void close(ResultSet rs) { - try - { - if (rs != null) - rs.close(); - } - catch (SQLException x) - { - log("Could not close result set!: " + x.toString()); + try { + if (rs != null) rs.close(); + } catch (SQLException x) { + log.warn("Could not close result set", x); } } @@ -511,7 +773,7 @@ public abstract class BaseManager implements DaoManager /** * Retrieves an int value from the passed result set as an Integer object. */ - public static Integer getInteger(ResultSet rs, int pos) throws SQLException { + protected static Integer getInteger(ResultSet rs, int pos) throws SQLException { int i = rs.getInt(pos); return rs.wasNull() ? (Integer)null : new Integer(i); } @@ -519,7 +781,7 @@ public abstract class BaseManager implements DaoManager /** * Retrieves an int value from the passed result set as an Integer object. */ - public static Integer getInteger(ResultSet rs, String column) throws SQLException { + protected static Integer getInteger(ResultSet rs, String column) throws SQLException { int i = rs.getInt(column); return rs.wasNull() ? (Integer)null : new Integer(i); } @@ -527,7 +789,7 @@ public abstract class BaseManager implements DaoManager /** * Set an Integer object to the passed prepared statement as an int or as null. */ - public static void setInteger(PreparedStatement ps, int pos, Integer i) throws SQLException { + protected static void setInteger(PreparedStatement ps, int pos, Integer i) throws SQLException { if (i==null) { ps.setNull(pos, Types.INTEGER); @@ -541,7 +803,7 @@ public abstract class BaseManager implements DaoManager /** * Retrieves a float value from the passed result set as a Float object. */ - public static Float getFloat(ResultSet rs, int pos) throws SQLException { + protected static Float getFloat(ResultSet rs, int pos) throws SQLException { float f = rs.getFloat(pos); return rs.wasNull() ? (Float)null : new Float(f); } @@ -549,7 +811,7 @@ public abstract class BaseManager implements DaoManager /** * Retrieves a float value from the passed result set as a Float object. */ - public static Float getFloat(ResultSet rs, String column) throws SQLException { + protected static Float getFloat(ResultSet rs, String column) throws SQLException { float f = rs.getFloat(column); return rs.wasNull() ? (Float)null : new Float(f); } @@ -557,7 +819,7 @@ public abstract class BaseManager implements DaoManager /** * Set a Float object to the passed prepared statement as a float or as null. */ - public static void setFloat(PreparedStatement ps, int pos, Float f) throws SQLException { + protected static void setFloat(PreparedStatement ps, int pos, Float f) throws SQLException { if (f==null) { ps.setNull(pos, Types.FLOAT); @@ -571,7 +833,7 @@ public abstract class BaseManager implements DaoManager /** * Retrieves a double value from the passed result set as a Double object. */ - public static Double getDouble(ResultSet rs, int pos) throws SQLException { + protected static Double getDouble(ResultSet rs, int pos) throws SQLException { double d = rs.getDouble(pos); return rs.wasNull() ? (Double)null : new Double(d); } @@ -579,7 +841,7 @@ public abstract class BaseManager implements DaoManager /** * Retrieves a double value from the passed result set as a Double object. */ - public static Double getDouble(ResultSet rs, String column) throws SQLException { + protected static Double getDouble(ResultSet rs, String column) throws SQLException { double d = rs.getDouble(column); return rs.wasNull() ? (Double)null : new Double(d); } @@ -587,7 +849,7 @@ public abstract class BaseManager implements DaoManager /** * Set a Double object to the passed prepared statement as a double or as null. */ - public static void setDouble(PreparedStatement ps, int pos, Double d) throws SQLException { + protected static void setDouble(PreparedStatement ps, int pos, Double d) throws SQLException { if (d==null) { ps.setNull(pos, Types.DOUBLE); @@ -601,7 +863,7 @@ public abstract class BaseManager implements DaoManager /** * Retrieves a long value from the passed result set as a Long object. */ - public static Long getLong(ResultSet rs, int pos) throws SQLException { + protected static Long getLong(ResultSet rs, int pos) throws SQLException { long l = rs.getLong(pos); return rs.wasNull() ? (Long)null : new Long(l); } @@ -609,7 +871,7 @@ public abstract class BaseManager implements DaoManager /** * Retrieves a long value from the passed result set as a Long object. */ - public static Long getLong(ResultSet rs, String column) throws SQLException { + protected static Long getLong(ResultSet rs, String column) throws SQLException { long l = rs.getLong(column); return rs.wasNull() ? (Long)null : new Long(l); } @@ -617,7 +879,7 @@ public abstract class BaseManager implements DaoManager /** * Set a Long object to the passed prepared statement as a long or as null. */ - public static void setLong(PreparedStatement ps, int pos, Long l) throws SQLException { + protected static void setLong(PreparedStatement ps, int pos, Long l) throws SQLException { if (l==null) { ps.setNull(pos, Types.BIGINT); @@ -631,7 +893,7 @@ public abstract class BaseManager implements DaoManager /** * Retrieves a boolean value from the passed result set as a Boolean object. */ - public static Boolean getBoolean(ResultSet rs, int pos) throws SQLException { + protected static Boolean getBoolean(ResultSet rs, int pos) throws SQLException { boolean b = rs.getBoolean(pos); return rs.wasNull() ? (Boolean)null : new Boolean(b); } @@ -639,7 +901,7 @@ public abstract class BaseManager implements DaoManager /** * Retrieves a boolean value from the passed result set as a Boolean object. */ - public static Boolean getBoolean(ResultSet rs, String column) throws SQLException { + protected static Boolean getBoolean(ResultSet rs, String column) throws SQLException { boolean b = rs.getBoolean(column); return rs.wasNull() ? (Boolean)null : new Boolean(b); } @@ -647,7 +909,7 @@ public abstract class BaseManager implements DaoManager /** * Set a Boolean object to the passed prepared statement as a boolean or as null. */ - public static void setBoolean(PreparedStatement ps, int pos, Boolean b) throws SQLException { + protected static void setBoolean(PreparedStatement ps, int pos, Boolean b) throws SQLException { if (b==null) { ps.setNull(pos, Types.BOOLEAN); @@ -829,7 +1091,7 @@ public abstract class BaseManager implements DaoManager * @param strDate the date as string. If (null or empty) or correct pattern was not found * @return Date object */ - static public java.util.Date getDateFromString(String strDate) + static protected java.util.Date getDateFromString(String strDate) { if (strDate != null) strDate = strDate.trim(); @@ -865,26 +1127,18 @@ public abstract class BaseManager implements DaoManager * @param strDate the date as string. * @return boolean "true" if the string represantes the date in one of the registed formats. */ - static public boolean isDate(String strDate) + static protected boolean isDate(String strDate) { - if (strDate != null) - strDate = strDate.trim(); - + if (strDate != null) strDate = strDate.trim(); SimpleDateFormat pSimpleDateFormat = new SimpleDateFormat(""); - if (strDate != null && "".equals(strDate) == false) - { - for (int i=0; i +{ + /** + * Invoked just before inserting a record into the database. + * + * @param bean the bean that is about to be inserted + */ + public void beforeInsert(T bean); + + /** + * Invoked just after a record is inserted in the database. + * + * @param bean the bean that was just inserted + */ + public void afterInsert(T bean); + + /** + * Invoked just before updating a record in the database. + * + * @param bean the bean that is about to be updated + */ + public void beforeUpdate(T bean); + + /** + * Invoked just after updating a record in the database. + * + * @param bean the bean that was just updated + */ + public void afterUpdate(T bean); + + /** + * Invoked just before deleting a record in the database. + * + * @param bean the bean that is about to be deleted + */ + public void beforeDelete(T bean); + + /** + * Invoked just after deleting a record in the database. + * + * @param bean the bean that was just deleted + */ + public void afterDelete(T bean); + +} diff --git a/src/main/resources/templates/velocity/table/listener.java.vm b/src/main/resources/templates/velocity/table/listener.java.vm deleted file mode 100755 index cd2b73b..0000000 --- a/src/main/resources/templates/velocity/table/listener.java.vm +++ /dev/null @@ -1,47 +0,0 @@ -##$Id: listener.java.vm,v 1.2 2005/10/10 20:11:48 framiere Exp $ -#parse( "header.include.vm" ) -#parse( "table.variables.include.vm" ) -$codewriter.setCurrentJavaFilename("$table.getPackage()", "${listenerClass}.java") -package $table.getPackage(); - -import java.sql.SQLException; - -import $pkg.*; - -/** - * Listener that is notified of $tablename table changes. - */ -public interface $listenerClass -{ - /** - * Invoked just before inserting a $beanClass record into the database. - * - * @param pObject the $beanClass that is about to be inserted - */ - public void beforeInsert($beanClass bean) throws SQLException; - - - /** - * Invoked just after a $beanClass record is inserted in the database. - * - * @param pObject the $beanClass that was just inserted - */ - public void afterInsert($beanClass bean) throws SQLException; - - - /** - * Invoked just before updating a $beanClass record in the database. - * - * @param pObject the $beanClass that is about to be updated - */ - public void beforeUpdate($beanClass bean) throws SQLException; - - - /** - * Invoked just after updating a $beanClass record in the database. - * - * @param pObject the $beanClass that was just updated - */ - public void afterUpdate($beanClass bean) throws SQLException; - -} diff --git a/src/main/resources/templates/velocity/table/manager.java.vm b/src/main/resources/templates/velocity/table/manager.java.vm index 14cb628..c6b5ccc 100644 --- a/src/main/resources/templates/velocity/table/manager.java.vm +++ b/src/main/resources/templates/velocity/table/manager.java.vm @@ -72,6 +72,26 @@ public class $managerClass extends BaseManager<$beanClass> + ",#else"#end$column.getName()"#end; + /** + * Contains all the full fields of the table. + */ + protected String[] getFullFieldNames() { return FULL_FIELD_NAMES; } + + /** + * Contains all the fields of the table. + */ + protected String[] getFieldNames() { return FIELD_NAMES; } + + /** + * Field that contains the comma separated fields of the table. + */ + protected String getAllFullFields() { return ALL_FULL_FIELDS; } + + /** + * Field that contains the comma separated fields of the table. + */ + protected String getAllFields() { return ALL_FIELDS; } + /** * Constructor */ @@ -140,8 +160,8 @@ public class $managerClass extends BaseManager<$beanClass> try { c = getConnection(); - StringBuffer sql = new StringBuffer("SELECT " + ALL_FIELDS + " FROM $tablename WHERE $sql"); - if (log.isTraceEnabled()) log.trace("loadByPrimaryKey: " + sql); + StringBuilder sql = new StringBuilder("SELECT " + ALL_FIELDS + " FROM $tablename WHERE $sql"); + if (log.isTraceEnabled()) log.trace("loadByPrimaryKey: {}", sql); ps = c.prepareStatement(sql.toString(), ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); @@ -179,8 +199,8 @@ public class $managerClass extends BaseManager<$beanClass> try { c = getConnection(); - StringBuffer sql = new StringBuffer("DELETE FROM $tablename WHERE $sql"); - if (log.isTraceEnabled()) log.trace("loadByPrimaryKey: " + sql); + StringBuilder sql = new StringBuilder("DELETE FROM $tablename WHERE $sql"); + if (log.isTraceEnabled()) log.trace("loadByPrimaryKey: {}", sql); ps = c.prepareStatement(sql.toString(), ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); @@ -244,88 +264,6 @@ public class $managerClass extends BaseManager<$beanClass> #end #end - ////////////////////////////////////// - // SQL 'WHERE' METHOD - ////////////////////////////////////// - /** - * Retrieves a List of $beanClass given a sql where clause and a list of fields, and startRow and numRows. - * It is up to you to pass the 'WHERE' in your where clausis. - * - * @param where the sql 'where' clause - * @param startRow the start row to be used (first row = 1, last row = -1) - * @param numRows the number of rows to be retrieved (all rows = a negative number) - * @param fieldList table of the field's associated constants - * @return the resulting $beanClass table - */ - //9 - public List<$beanClass> loadByWhere(String where, int[] fieldList, int startRow, int numRows) throws SQLException - { - String sql = null; - if(fieldList == null) - sql = "SELECT " + ALL_FIELDS + " FROM $tablename " + where; - else - { - StringBuffer buff = new StringBuffer(128); - buff.append("SELECT "); - for(int i = 0; i < fieldList.length; i++) - { - if(i != 0) - buff.append(","); - buff.append(FIELD_NAMES[fieldList[i]]); - } - buff.append(" FROM $tablename "); - buff.append(where); - sql = buff.toString(); - buff = null; - } - Connection c = null; - Statement st = null; - ResultSet rs = null; - if (log.isTraceEnabled()) log.trace("loadByWhere: " + sql); - try - { - c = getConnection(); - st = c.createStatement(); - rs = st.executeQuery(sql); - return decodeResultSet(rs, fieldList, startRow, numRows); - } - finally - { - sql = null; - close(st, rs); - releaseConnection(c); - } - } - - /** - * Deletes rows from the $tablename table using a 'where' clause. - * It is up to you to pass the 'WHERE' in your where clausis. - *
Attention, if 'WHERE' is omitted it will delete all records. - * - * @param where the sql 'where' clause - * @return the number of deleted rows - */ - //11 - public int deleteByWhere(String where) throws SQLException - { - Connection c = null; - PreparedStatement ps = null; - - try - { - c = getConnection(); - StringBuffer sql = new StringBuffer("DELETE FROM $tablename " + where); - if (log.isTraceEnabled()) log.trace("deleteByWhere: " + sql); - ps = c.prepareStatement(sql.toString()); - return ps.executeUpdate(); - } - finally - { - close(ps); - releaseConnection(c); - } - } - //_____________________________________________________________________ // // SAVE @@ -350,7 +288,7 @@ public class $managerClass extends BaseManager<$beanClass> Connection c = null; PreparedStatement ps = null; - StringBuffer sql = null; + StringBuilder sql = null; try { @@ -362,9 +300,8 @@ public class $managerClass extends BaseManager<$beanClass> #if ( $genKeyRetrieve == "before" && $primaryKeys.size() == 1 && $pKey.isColumnNumeric() ) if (!bean.$strUtil.getModifiedMethod($pKey)()) { - StringBuffer hint = new StringBuffer("$hint"); - if (log.isTraceEnabled()) log.trace("generatedKey : " + hint); - + StringBuilder hint = new StringBuilder("$hint"); + if (log.isTraceEnabled()) log.trace("generatedKey : {}", hint); ps = c.prepareStatement(hint.toString()); ResultSet rs = null; try @@ -373,7 +310,7 @@ public class $managerClass extends BaseManager<$beanClass> if(rs.next()) bean.$strUtil.getSetMethod($pKey)($pKey.getResultSetMethodObject("1")); else - log("ATTENTION: Could not retrieve generated key!"); + log.warn("Could not retrieve generated key"); } finally { @@ -390,7 +327,7 @@ public class $managerClass extends BaseManager<$beanClass> bean.$strUtil.getSetMethod($lockColumn)(new $lockColumn.getJavaType()(String.valueOf(System.curentTimeMillis()))); #end - sql = new StringBuffer(); + sql = new StringBuilder(); if (delayed) sql.append("INSERT DELAYED into $tablename ("); else sql.append("INSERT into $tablename ("); @@ -435,9 +372,7 @@ public class $managerClass extends BaseManager<$beanClass> #end } - - if (log.isTraceEnabled()) log.trace("insert : " + sql.toString()); - + if (log.isTraceEnabled()) log.trace("insert : {}", sql); ps = c.prepareStatement(sql.toString(), $prestArgs); @@ -461,7 +396,7 @@ public class $managerClass extends BaseManager<$beanClass> if(rs.next()) { bean.$strUtil.getSetMethod($pKey)($pKey.getResultSetMethodObject("1")); } else { - log("ATTENTION: Could not retrieve generated key!"); + log.warn("Could not retrieve generated key"); } } finally { close(ps2, rs); @@ -475,7 +410,7 @@ public class $managerClass extends BaseManager<$beanClass> if(rs.next()) bean.$strUtil.getSetMethod($pKey)($pKey.getResultSetMethodObject("1")); else - log("ATTENTION: Could not retrieve auto generated key!"); + log.warn("Could not retrieve auto generated key"); } finally { close(rs); } @@ -515,7 +450,7 @@ public class $managerClass extends BaseManager<$beanClass> Connection c = null; PreparedStatement ps = null; - StringBuffer sql = null; + StringBuilder sql = null; try { @@ -529,7 +464,7 @@ $codewriter.log(" WARN : $tablename does not have any primary key...") bean.$strUtil.getSetMethod($lockColumn))(new $lockColumn.getJavaType()(String.valueOf(System.currentTimeMillis()))); #end - sql = new StringBuffer("UPDATE $tablename SET "); + sql = new StringBuilder("UPDATE $tablename SET "); boolean useComma=false; #foreach( $column in $columns ) @@ -558,7 +493,7 @@ $codewriter.log(" WARN : $tablename does not have any primary key...") #sqlAppend( "$lockColumn.getName()=?") #end sql.append("$sql"); - if (log.isTraceEnabled()) log.trace("update : " + sql.toString()); + if (log.isTraceEnabled()) log.trace("update : {}", sql); ps = c.prepareStatement(sql.toString(), ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); @@ -593,60 +528,11 @@ $codewriter.log(" WARN : $tablename does not have any primary key...") } } - //_____________________________________________________________________ // // USING TEMPLATE //_____________________________________________________________________ - /** - * Loads a List of $beanClass from a template one, given the start row and number of rows. - * - * @param bean the $beanClass template to look for - * @param startRow the start row to be used (first row = 1, last row=-1) - * @param numRows the number of rows to be retrieved (all rows = a negative number) - * @param searchType exact ? like ? starting like ? - * @return all the $beanClass matching the template - */ - //20 - public List<$beanClass> loadUsingTemplate($beanClass bean, int startRow, int numRows, int searchType) throws SQLException - { - if (log.isTraceEnabled()) log.trace("loadUsingTemplate startRow:" + startRow + ", numRows:" + numRows + ", searchType:" + searchType); - Connection c = null; - PreparedStatement ps = null; - StringBuffer sql = new StringBuffer("SELECT " + ALL_FIELDS + " FROM $tablename "); - StringBuffer sqlWhere = new StringBuffer(""); - - try - { - if (fillWhere(sqlWhere, bean, searchType) == 0) { - if (log.isTraceEnabled()) log.trace("The bean to look is not initialized... loading all"); - } else { - sql.append(" WHERE ").append(sqlWhere); - } - if (log.isTraceEnabled()) log.trace("loadUsingTemplate: " + sql.toString()); - - c = getConnection(); - int scrollType = ResultSet.TYPE_SCROLL_INSENSITIVE; - if (startRow != 1) - scrollType = ResultSet.TYPE_SCROLL_SENSITIVE; - ps = c.prepareStatement(sql.toString(), - scrollType, - ResultSet.CONCUR_READ_ONLY); - fillPreparedStatement(ps, bean, searchType); - - //ps.executeQuery(); - return loadByPreparedStatement(ps, null, startRow, numRows); - } - finally - { - close(ps); - releaseConnection(c); - sql = null; - sqlWhere = null; - } - } - /** * Deletes rows using a $beanClass template. * @@ -663,8 +549,8 @@ $codewriter.log(" WARN : $tablename does not have any primary key...") #end Connection c = null; PreparedStatement ps = null; - StringBuffer sql = new StringBuffer("DELETE FROM $tablename ");; - StringBuffer sqlWhere = new StringBuffer(""); + StringBuilder sql = new StringBuilder("DELETE FROM $tablename ");; + StringBuilder sqlWhere = new StringBuilder(""); try { @@ -673,7 +559,7 @@ $codewriter.log(" WARN : $tablename does not have any primary key...") } else { sql.append(" WHERE ").append(sqlWhere); } - if (log.isTraceEnabled()) log.trace("deleteUsingTemplate: " + sql.toString()); + if (log.isTraceEnabled()) log.trace("deleteUsingTemplate: {}", sql); c = getConnection(); ps = c.prepareStatement(sql.toString(), @@ -693,137 +579,22 @@ $codewriter.log(" WARN : $tablename does not have any primary key...") } } - - //_____________________________________________________________________ - // - // COUNT - //_____________________________________________________________________ - - /** - * Retrieves the number of rows of the table $tablename with a 'where' clause. - * It is up to you to pass the 'WHERE' in your where clausis. - * - * @param where the restriction clause - * @return the number of rows returned - */ - //25 - public int countWhere(String where) throws SQLException - { - String sql = "SELECT COUNT(*) AS MCOUNT FROM $tablename " + where; - if (log.isTraceEnabled()) log.trace("countWhere: " + sql); - Connection c = null; - Statement st = null; - ResultSet rs = null; - try - { - int iReturn = -1; - c = getConnection(); - st = c.createStatement(); - rs = st.executeQuery(sql); - if (rs.next()) - { - iReturn = rs.getInt("MCOUNT"); - } - if (iReturn != -1) - return iReturn; - } - finally - { - close(st, rs); - releaseConnection(c); - sql = null; - } - throw new SQLException("Error in countWhere"); - } - - /** - * Retrieves the number of rows of the table $tablename with a prepared statement. - * - * @param ps the PreparedStatement to be used - * @return the number of rows returned - */ - //26 - int countByPreparedStatement(PreparedStatement ps) throws SQLException - { - ResultSet rs = null; - try - { - int iReturn = -1; - rs = ps.executeQuery(); - if (rs.next()) - iReturn = rs.getInt("MCOUNT"); - if (iReturn != -1) - return iReturn; - } - finally - { - close(rs); - } - throw new SQLException("Error in countByPreparedStatement"); - } - - /** - * count the number of elements of a specific $beanClass bean given the start row and number of rows and the search type - * - * @param bean the $beanClass template to look for - * @param startRow the start row to be used (first row = 1, last row=-1) - * @param numRows the number of rows to be retrieved (all rows = a negative number) - * @param searchType exact ? like ? starting like ? - * @return the number of rows returned - */ - //20 - public int countUsingTemplate($beanClass bean, int startRow, int numRows, int searchType) throws SQLException - { - Connection c = null; - PreparedStatement ps = null; - StringBuffer sql = new StringBuffer("SELECT COUNT(*) AS MCOUNT FROM $tablename"); - StringBuffer sqlWhere = new StringBuffer(""); - - try - { - if (fillWhere(sqlWhere, bean, SEARCH_EXACT) == 0) { - if (log.isTraceEnabled()) log.trace("The bean to look is not initialized... counting all..."); - } else { - sql.append(" WHERE ").append(sqlWhere); - } - if (log.isTraceEnabled()) log.trace("countUsingTemplate: " + sql.toString()); - - c = getConnection(); - ps = c.prepareStatement(sql.toString(), - ResultSet.TYPE_SCROLL_INSENSITIVE, - ResultSet.CONCUR_READ_ONLY); - fillPreparedStatement(ps, bean, searchType); - - return countByPreparedStatement(ps); - } - finally - { - close(ps); - releaseConnection(c); - sql = null; - sqlWhere = null; - } - } - - // - - /** - * fills the given stringbuffer with the sql where clausis constructed using the bean and the search type - * @param sqlWhere the stringbuffer that will be filled + * fills the given stringbuilder with the sql where clausis constructed using the bean and the search type + * @param sqlWhere the stringbuilder that will be filled * @param bean the bean to use for creating the where clausis * @param searchType exact ? like ? starting like ? * @return the number of clausis returned */ - protected int fillWhere(StringBuffer sqlWhere, $beanClass bean, int searchType) throws SQLException + protected int fillWhere(StringBuilder sqlWhere, $beanClass bean, int searchType) throws SQLException { if (bean == null) return 0; int _dirtyCount = 0; - StringBuffer sqlEqualsOperation = new StringBuffer("="); - StringBuffer sqlOperation = new StringBuffer("="); + StringBuilder sqlEqualsOperation = new StringBuilder("="); + StringBuilder sqlOperation = new StringBuilder("="); if (searchType != SEARCH_EXACT) - sqlOperation = new StringBuffer(" like "); + sqlOperation = new StringBuilder(" like "); try { #foreach( $column in $columns ) @@ -862,24 +633,24 @@ $codewriter.log(" WARN : $tablename does not have any primary key...") #if ($column.isString()) switch (searchType){ case SEARCH_EXACT: - if (log.isTraceEnabled()) log.trace("Setting for " + _dirtyCount + " [" + bean.$strUtil.getGetMethod($column)() + "]"); + if (log.isTraceEnabled()) log.trace("Setting for {} [{}]", _dirtyCount, bean.$strUtil.getGetMethod($column)()); $column.getPreparedStatementMethod("bean.$strUtil.getGetMethod($column)()", "++_dirtyCount"); break; case SEARCH_LIKE: - if (log.isTraceEnabled()) log.trace("Setting for " + _dirtyCount + " [%" + bean.$strUtil.getGetMethod($column)() + "%]"); + if (log.isTraceEnabled()) log.trace("Setting for {} [%{}%]", _dirtyCount, bean.$strUtil.getGetMethod($column)()); $column.getPreparedStatementMethod("${Q}%${Q} + bean.$strUtil.getGetMethod($column)() + ${Q}%${Q}", "++_dirtyCount"); break; case SEARCH_STARTING_LIKE: - if (log.isTraceEnabled()) log.trace("Setting for " + _dirtyCount + " [" + bean.$strUtil.getGetMethod($column)() + "%]"); + if (log.isTraceEnabled()) log.trace("Setting for {} [{}%]", _dirtyCount, bean.$strUtil.getGetMethod($column)()); $column.getPreparedStatementMethod("${Q}%${Q} + bean.$strUtil.getGetMethod($column)()", "++_dirtyCount"); break; case SEARCH_ENDING_LIKE: - if (log.isTraceEnabled()) log.trace("Setting for " + _dirtyCount + " [%" + bean.$strUtil.getGetMethod($column)() + "]"); + if (log.isTraceEnabled()) log.trace("Setting for {} [%{}]", _dirtyCount, bean.$strUtil.getGetMethod($column)()); $column.getPreparedStatementMethod("bean.$strUtil.getGetMethod($column)() + ${Q}%${Q}", "++_dirtyCount"); break; } #else - if (log.isTraceEnabled()) log.trace("Setting for " + _dirtyCount + " [" + bean.$strUtil.getGetMethod($column)() + "]"); + if (log.isTraceEnabled()) log.trace("Setting for {} [{}]", _dirtyCount, bean.$strUtil.getGetMethod($column)()); $column.getPreparedStatementMethod("bean.$strUtil.getGetMethod($column)()", "++_dirtyCount"); #end } @@ -887,13 +658,6 @@ $codewriter.log(" WARN : $tablename does not have any primary key...") return _dirtyCount; } - - //_____________________________________________________________________ - // - // DECODE RESULT SET - //_____________________________________________________________________ - - /** * Transforms a ResultSet iterating on the $tablename on a $beanClass bean. * From 24be004935f6cd77461d568827c5abd3134b49b5 Mon Sep 17 00:00:00 2001 From: garthpatil Date: Mon, 24 Sep 2012 18:00:09 -0700 Subject: [PATCH 06/11] finished maven plugin. moved templates. added some documentation. --- README.md | 52 +- pom.xml | 4 +- .../net/sourceforge/sql2java/CodeWriter.java | 254 +++++----- .../java/net/sourceforge/sql2java/Main.java | 2 +- .../sql2java/maven/Sql2JavaMojo.java | 139 ++++-- .../velocity/global => }/basemanager.java.vm | 446 ++++++++---------- .../velocity/table => }/bean.java.vm | 0 .../velocity/global => }/daobean.java.vm | 0 .../velocity/global => }/daomanager.java.vm | 13 +- .../velocity/includes => }/header.include.vm | 0 .../velocity/table => }/manager.java.vm | 151 ++---- .../includes => }/table.variables.include.vm | 0 .../velocity/global/baselistener.java.vm | 71 --- .../velocity/global/cachingmanager.java.vm | 114 ----- .../velocity/global/listener.java.vm | 55 --- .../velocity/global/managerfactory.java.vm | 29 -- .../velocity/table/comparator.java.vm | 104 ---- src/{ => test}/config/test.properties | 9 +- 18 files changed, 488 insertions(+), 955 deletions(-) rename src/main/resources/{templates/velocity/global => }/basemanager.java.vm (74%) rename src/main/resources/{templates/velocity/table => }/bean.java.vm (100%) rename src/main/resources/{templates/velocity/global => }/daobean.java.vm (100%) rename src/main/resources/{templates/velocity/global => }/daomanager.java.vm (81%) rename src/main/resources/{templates/velocity/includes => }/header.include.vm (100%) rename src/main/resources/{templates/velocity/table => }/manager.java.vm (89%) rename src/main/resources/{templates/velocity/includes => }/table.variables.include.vm (100%) delete mode 100644 src/main/resources/templates/velocity/global/baselistener.java.vm delete mode 100755 src/main/resources/templates/velocity/global/cachingmanager.java.vm delete mode 100755 src/main/resources/templates/velocity/global/listener.java.vm delete mode 100644 src/main/resources/templates/velocity/global/managerfactory.java.vm delete mode 100755 src/main/resources/templates/velocity/table/comparator.java.vm rename src/{ => test}/config/test.properties (92%) diff --git a/README.md b/README.md index 946c008..dcab2c8 100644 --- a/README.md +++ b/README.md @@ -1,30 +1,62 @@ # sql2java # -This is a fork of a project on SourceForge by the same name . It is heavily modified from the original version. I started using this around 2005 as a quick & dirty way to generate Java beans and data access managers from a SQL database. Here I am, 7+ years later, still using it, totally underwhelmed with the state of ORM tools like Hibernate. The short of it is, if you know SQL, there's no reason to use an ORM that hides it from you. If you don't, well, you're probably screwed on the performance front, so you should switch to Ruby On Rails anyways, as you'll be much more productive. The only thing that looks interesting to me these days is JDBI which puts nice Java idioms on top of SQL and JDBC. Otherwise, for trivial projects where I'm just ripping strings in and out of databases, I'll probably keep using this for another 7 years. +This is a fork of an abandoned project on SourceForge by the same name . It is heavily modified from the original version. I started using this around 2005 as a quick & dirty way to generate Java beans and data access managers from a SQL database. I still use it, as I have found many ORM tools like Hibernate to be unweildy and more trouble than they're worth. Other things that looks interesting to me these days are JDBI which puts nice Java idioms on top of SQL and JDBC, ActiveJDBC which walks a nice line between JDBC and the active record pattern, and Ebean which is an ORM, but feels right. This differs from the original project in the following ways: -- Build uses Maven. Will be packaged as a Maven plugin in the future. +- Build uses Maven. Packaged as a Maven plugin. - No more web widgets or factories. Just beans and managers. -- Manager class is gone. BaseManager now take a DataSource directly. +- *Managers return Lists instead of arrays. +- Manager class is gone. BaseManager now takes a DataSource directly. - Uses generics to make the code more concise (and requires Java 1.5) - Not sure if anything but MySQL and HSQL support works anymore. PostgreSQL did work a while ago, but haven't checked in a bit. +To do in the future: +- Add an interface for a cache providing a few convenience methods on top of a *Manager: T get(Id), List get(List), List get(Key) +- Provide a optional runtime library with cache implementations. +- The CodeWriter and Database classes are messy and fragile. Port to use SchemaCrawler +- Generate a (SchemaName)Database.java factory with get*Manager() methods for all managers. This would be an easy entry point to extend as your applications DAO. +- Transactions? +- Do something with foreign key mappings that is sane against bad definitions? + ### Using: ### -To try it out, edit src/config/test.properties to reflect your databases's properties, and run: +To try it out, copy src/test/config/test.properties into your project and edit to reflect your databases's properties. + +Add the following to your POM file's build section: -./run.sh src/config/test.properties + + + + net.sourceforge + sql2java-maven-plugin + 1.0-SNAPSHOT + + + sql2java + + sql2java + + + + + ${project.basedir}/src/main/java + ${project.basedir}/src/main/resources/sql2java.properties + + + ... + + -Which just uses Maven exec:java to run: +And run: -mvn -e exec:java -Dexec.classpathScope="runtime" -Dexec.mainClass="net.sourceforge.sql2java.Main" -Dexec.args="src/config/test.properties" + mvn sql2java:sql2java compile -Generated classes will appear in target/generated-sources/ or wherever you configured in src/config/test.properties. There is a log at target/velocity.log that will tell you if anything failed, and running Maven with the -e flag should be somewhat informative. +There is a log at target/velocity.log that will tell you if anything failed, and running Maven with the -e flag should be somewhat informative. ### Customizing: ### -The Velocity templates used by the code generator are in src/main/resources/templates/velocity. The per-schema templates are in the global/ subdirectory, and the per-table templates are in the table/ subdirectory. If you add a new template to either directory, you must specify it in your properties file under mgrwriter.templates.perschema or mgrwriter.templates.pertable. +The Velocity templates used by the code generator are in src/main/resources. If you add a new template, you must specify it in your properties file under mgrwriter.templates.perschema or mgrwriter.templates.pertable. ### Dependencies: ### -- Runtime dependencies for the generated code are slf4j for logging, whatever JDBC driver you need for your database, and google-guava for Immutable Lists/Maps and caching. +- Runtime dependencies for the generated code are slf4j for logging, and whatever JDBC driver you need for your database. ### Feedback: ### Please submit a pull request if you'd like to see something changed. diff --git a/pom.xml b/pom.xml index 09724af..092f1d3 100644 --- a/pom.xml +++ b/pom.xml @@ -25,12 +25,12 @@ velocity velocity - 1.3.1 + 1.5 velocity velocity-dep - 1.3.1 + 1.4 hsqldb diff --git a/src/main/java/net/sourceforge/sql2java/CodeWriter.java b/src/main/java/net/sourceforge/sql2java/CodeWriter.java index a1e1450..7d7fd78 100755 --- a/src/main/java/net/sourceforge/sql2java/CodeWriter.java +++ b/src/main/java/net/sourceforge/sql2java/CodeWriter.java @@ -13,6 +13,9 @@ import org.apache.velocity.app.FieldMethodizer; import org.apache.velocity.VelocityContext; import org.apache.velocity.exception.*; +import org.apache.velocity.runtime.RuntimeConstants; +import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader; + // this class is a mess, would need some brushing, however the generated code is clean and // that's what really matters @@ -51,7 +54,7 @@ public class CodeWriter public CodeWriter (Database db, Properties props) { try { this.db = db; - this.props = props; + this.props = props; dateClassName = props.getProperty("jdbc2java.date", "java.sql.Date"); timeClassName = props.getProperty("jdbc2java.time", "java.sql.Time"); @@ -72,15 +75,11 @@ public CodeWriter (Database db, Properties props) { optimisticLockType = props.getProperty("optimisticlock.type", "none"); optimisticLockColumn = props.getProperty("optimisticlock.column"); - if(basePackage == null) - { - throw new Exception("Missing property: mgrwriter.package"); - } - + if(basePackage == null) throw new Exception("Missing property: mgrwriter.package"); } catch (Exception e) { - //knishikawa - maybe this needs better exception handling for the Velocity inits - System.err.println("Threw an exception in the CodeWriter constructor:" + e.getMessage()); - e.printStackTrace(); + //knishikawa - maybe this needs better exception handling for the Velocity inits + System.err.println("Threw an exception in the CodeWriter constructor:" + e.getMessage()); + e.printStackTrace(); } } @@ -88,10 +87,7 @@ public CodeWriter (Database db, Properties props) { public void setDestinationFolder(String destDir) throws Exception { this.destDir = destDir; - if(destDir == null) - { - throw new Exception("Missing property: mgrwriter.destdir"); - } + if(destDir == null) throw new Exception("Missing property: mgrwriter.destdir"); File dir = new File(destDir); try { @@ -100,29 +96,23 @@ public void setDestinationFolder(String destDir) throws Exception // ignore } - if(!dir.isDirectory() || !dir.canWrite()) - { - throw new Exception("Cannot write to: " + destDir); - } + if(!dir.isDirectory() || !dir.canWrite()) throw new Exception("Cannot write to: " + destDir); } private Hashtable setHash(String str) { - if(str == null || str.trim().equals("")) + if (str == null || str.trim().equals("")) { return new Hashtable(); - else - { - Hashtable hash = new Hashtable(); - StringTokenizer st = new StringTokenizer(str); - while(st.hasMoreTokens()) - { - String val = st.nextToken().toLowerCase(); - hash.put(val, val); - } - - return hash; - } + } else { + Hashtable hash = new Hashtable(); + StringTokenizer st = new StringTokenizer(str); + while(st.hasMoreTokens()) { + String val = st.nextToken().toLowerCase(); + hash.put(val, val); + } + return hash; + } } public boolean checkTable(Table table) throws Exception @@ -130,44 +120,35 @@ public boolean checkTable(Table table) throws Exception System.out.println(" checking table " + table.getName() + " ..."); boolean error = false; Column primaryKeys[] = table.getPrimaryKeys(); - if (table.getColumns().length == 0) - { - System.err.println(" WARN : no column found !"); - error = false; - } - if (primaryKeys.length == 0) - { - System.err.println(" WARN : No primary key is defined on table " + table.getName()); - System.err.println(" Tables without primary key are not fully supported"); - error = false; - } - else - { - if (primaryKeys.length > 1) - { - System.err.print(" WARN : Composite primary key "); - for (int ii = 0; ii < primaryKeys.length; ii++) - System.err.print(primaryKeys[ii].getFullName() + ", "); - System.err.println(); - System.err.println(" Tables with composite primary key are not fully supported"); - } - else - { - Column pk = primaryKeys[0]; - String pkName = pk.getName(); - String normalKey = table.getName() + "_id"; - if (pkName.equalsIgnoreCase(normalKey) == false) - { - System.err.println(" WARN : primary key should of form _ID"); - System.err.println(" found " + pkName + " expected " + normalKey); - } - if (pk.isColumnNumeric() == false) - { - System.err.println(" WARN : primary key should be an integer "); - System.err.println(" found " + pk.getJavaType()); - } - } - } + if (table.getColumns().length == 0) { + System.err.println(" WARN : no column found !"); + error = false; + } + if (primaryKeys.length == 0) { + System.err.println(" WARN : No primary key is defined on table " + table.getName()); + System.err.println(" Tables without primary key are not fully supported"); + error = false; + } else { + if (primaryKeys.length > 1) { + System.err.print(" WARN : Composite primary key "); + for (int ii = 0; ii < primaryKeys.length; ii++) + System.err.print(primaryKeys[ii].getFullName() + ", "); + System.err.println(); + System.err.println(" Tables with composite primary key are not fully supported"); + } else { + Column pk = primaryKeys[0]; + String pkName = pk.getName(); + String normalKey = table.getName() + "_id"; + if (pkName.equalsIgnoreCase(normalKey) == false) { + System.err.println(" WARN : primary key should of form _ID"); + System.err.println(" found " + pkName + " expected " + normalKey); + } + if (pk.isColumnNumeric() == false) { + System.err.println(" WARN : primary key should be an integer "); + System.err.println(" found " + pk.getJavaType()); + } + } + } return error; } @@ -176,45 +157,32 @@ public void checkDatabase() throws Exception System.out.println("Checking database tables"); boolean error = false; Table tables[] = db.getTables(); - for (int i = 0; i < tables.length; i++) - { - if (includeHash.size() != 0) - { - if (includeHash.get(tables[i].getName().toLowerCase()) != null) - { - if (excludeHash.get(tables[i].getName().toLowerCase()) == null) - { - boolean b = checkTable(tables[i]); - if (b == true) - error = true; - } - } - } - else - { - if (excludeHash.size() != 0) - { - if (excludeHash.get(tables[i].getName().toLowerCase()) == null) - { - boolean b = checkTable(tables[i]); - if (b == true) - error = true; - } - } - else - { - boolean b = checkTable(tables[i]); - if (b == true) - error = true; - } - } - } - if (error == true) - { - System.err.println(" Failed : at least one of the mandatory rule for sql2java is followed by your schema."); - System.err.println(" Please check the documentation for more information"); - System.exit(-1); - } + for (int i = 0; i < tables.length; i++) { + if (includeHash.size() != 0) { + if (includeHash.get(tables[i].getName().toLowerCase()) != null) { + if (excludeHash.get(tables[i].getName().toLowerCase()) == null) { + boolean b = checkTable(tables[i]); + if (b == true) + error = true; + } + } + } else { + if (excludeHash.size() != 0) { + if (excludeHash.get(tables[i].getName().toLowerCase()) == null) { + boolean b = checkTable(tables[i]); + if (b == true) error = true; + } + } else { + boolean b = checkTable(tables[i]); + if (b == true) error = true; + } + } + } + if (error == true) { + System.err.println(" Failed : at least one of the mandatory rule for sql2java is followed by your schema."); + System.err.println(" Please check the documentation for more information"); + System.exit(-1); + } System.out.println(" Passed."); } @@ -225,17 +193,23 @@ public void checkDatabase() throws Exception /** The entry point for generating code. */ public synchronized void process() throws Exception { - if ("true".equalsIgnoreCase(Main.getProperty("check.database"))) + if ("true".equalsIgnoreCase(props.getProperty("check.database"))) checkDatabase(); - if ("true".equalsIgnoreCase(Main.getProperty("check.only.database"))) + if ("true".equalsIgnoreCase(props.getProperty("check.only.database"))) return; // Init Velocity Properties vprops = new Properties(); vprops.put("runtime.log", "target/velocity.log"); - vprops.put("file.resource.loader.path", getProperty("mgrwriter.templates.loadingpath",".") ); - + vprops.put(RuntimeConstants.RESOURCE_LOADER, "classpath"); + vprops.put("classpath.resource.loader.class", ClasspathResourceLoader.class.getName()); + // for file and class + // vprops.put(RuntimeConstants.RESOURCE_LOADER, "file, classpath"); + // vprops.put("file.resource.loader.class", FileResourceLoader.class.getName()); + // vprops.put("file.resource.loader.path", getProperty("mgrwriter.templates.loadingpath",".") ); + // vprops.put("classpath.resource.loader.class", ClasspathResourceLoader.class.getName()); + Velocity.init(vprops); vc = new VelocityContext(); vc.put("CodeWriter", new FieldMethodizer( this )); @@ -250,7 +224,7 @@ public synchronized void process() throws Exception for(int i=0; i"); + System.err.println("Usage: java net.sourceforge.sql2java.Main "); System.exit(1); } diff --git a/src/main/java/net/sourceforge/sql2java/maven/Sql2JavaMojo.java b/src/main/java/net/sourceforge/sql2java/maven/Sql2JavaMojo.java index 4320598..deb2bcd 100644 --- a/src/main/java/net/sourceforge/sql2java/maven/Sql2JavaMojo.java +++ b/src/main/java/net/sourceforge/sql2java/maven/Sql2JavaMojo.java @@ -1,64 +1,131 @@ package net.sourceforge.sql2java.maven; +import net.sourceforge.sql2java.*; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import java.io.File; -import java.io.FileWriter; +import java.io.FileInputStream; import java.io.IOException; +import java.util.ArrayList; +import java.util.Properties; +import java.util.StringTokenizer; /** - * Goal which touches a timestamp file. - * - * @goal touch - * - * @phase process-sources + * Goal which uses a sql2java to generate Java files from a SQL database. + * @goal sql2java + * @requiresDirectInvocation true + * @author garth */ public class Sql2JavaMojo extends AbstractMojo { + /** - * Location of the file. - * @parameter expression="${project.build.directory}" + * The working directory where the generated Java source files are created. + * + * @parameter default-value="${project.build.directory}/generated-sources/sql2java" * @required */ private File outputDirectory; - public void execute() - throws MojoExecutionException + protected File getOutputDirectory() { - File f = outputDirectory; + return outputDirectory; + } - if ( !f.exists() ) - { + /** + * The location of the properties file. + * + * @parameter default-value="${project.basedir}/src/main/resources/sql2java.properties" + * @required + */ + private File propertiesFile; + + protected File getPropertiesFile() + { + return propertiesFile; + } + + public void execute() throws MojoExecutionException { + File f = outputDirectory; + if ( !f.exists() ) { f.mkdirs(); } - File touch = new File( f, "touch.txt" ); - - FileWriter w = null; - try - { - w = new FileWriter( touch ); + if ( !propertiesFile.exists() ) { + throw new MojoExecutionException(propertiesFile.getName() + " doesn't exist!"); + } - w.write( "touch.txt" ); - } - catch ( IOException e ) - { - throw new MojoExecutionException( "Error creating file " + touch, e ); + //properties already here ? + Properties prop = new Properties(); + try { + prop.load(new FileInputStream(propertiesFile)); + Database db = new Database(); + db.setDriver(getProperty(prop, "jdbc.driver")); + db.setUrl(getProperty(prop, "jdbc.url")); + db.setUsername(getProperty(prop, "jdbc.username")); + db.setPassword(getProperty(prop, "jdbc.password")); + db.setCatalog(getProperty(prop, "jdbc.catalog")); + db.setSchema(getProperty(prop, "jdbc.schema")); + db.setTableNamePattern(getProperty(prop, "jdbc.tablenamepattern")); + + if ("false".equalsIgnoreCase(getProperty(prop, "jdbc.oracle.retrieve.remarks"))) + db.setOracleRetrieveRemarks(false); + else + db.setOracleRetrieveRemarks(true); + + String tt = getProperty(prop, "jdbc.tabletypes", "TABLE"); + StringTokenizer st = new StringTokenizer(tt, ",; \t"); + ArrayList al = new ArrayList(); + + while(st.hasMoreTokens()) { + al.add(((String)st.nextToken()).trim()); + } + + db.setTableTypes((String[])al.toArray(new String[al.size()])); + + db.load(); + + CodeWriter writer = new CodeWriter(db, prop); + // override destdir if given + writer.setDestinationFolder(outputDirectory.getPath()); + writer.process(); + } catch(Exception e) { + throw new MojoExecutionException("Error executing plugin", e); } - finally + + } + + public static String getProperty(Properties prop, String key) + { + String s = prop.getProperty(key); + return s!=null?s.trim():s; + } + + /** + * helper method with default values + */ + public static String getProperty(Properties prop, String key, String default_val) + { + String s = getProperty(prop, key); + if (s == null) + return default_val; + return s; + } + + /** + * is the given code in the string array ? + */ + public static boolean isInArray(String[] ar, String code) + { + if (ar == null) + return false; + for (int i = 0; i < ar.length; i ++) { - if ( w != null ) - { - try - { - w.close(); - } - catch ( IOException e ) - { - // ignore - } - } + if (code.equalsIgnoreCase(ar[i])) + return true; } + return false; } + } diff --git a/src/main/resources/templates/velocity/global/basemanager.java.vm b/src/main/resources/basemanager.java.vm similarity index 74% rename from src/main/resources/templates/velocity/global/basemanager.java.vm rename to src/main/resources/basemanager.java.vm index 502ad02..2ef73c0 100644 --- a/src/main/resources/templates/velocity/global/basemanager.java.vm +++ b/src/main/resources/basemanager.java.vm @@ -3,18 +3,20 @@ $codewriter.setCurrentJavaFilename($pkg, "BaseManager.java") package $pkg; +import java.math.BigDecimal; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.sql.Types; +import java.text.ParseException; +import java.text.SimpleDateFormat; import java.util.ArrayList; +import java.util.Calendar; import java.util.Collections; import java.util.List; import javax.sql.DataSource; -import java.text.SimpleDateFormat; -import java.util.Calendar; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -39,7 +41,6 @@ public abstract class BaseManager implements DaoManager } protected DataSource dataSource; - protected Listener listener; /** * Contains all the full fields of the table. @@ -61,13 +62,6 @@ public abstract class BaseManager implements DaoManager */ protected abstract String getAllFields(); - /** - * Set the listener for INSERT/UPDATE/DELETE operations. - */ - public void setListener(Listener listener) { - this.listener = listener; - } - /** * Loads an object from the table using its key field. * @@ -127,48 +121,21 @@ public abstract class BaseManager implements DaoManager * @return the resulting bean */ public List loadByWhere(String where) throws SQLException { - return loadByWhere(where, null); + return loadByWhere(where, null, 1, -1); } /** - * Retrieves a List of beans given a sql where clause, and a list of fields. - * It is up to you to pass the 'WHERE' in your where clausis. - * - * @param where the sql 'WHERE' clause - * @param fieldList array of field's ID - * @return the resulting beans - */ - public List loadByWhere(String where, int[] fieldList) throws SQLException { - return loadByWhere(where, fieldList, 1, -1); - } - - /** - * Retrieves a List of beans given a sql where clause and a list of fields, and startRow and numRows. + * Retrieves a List of beans given a sql where clause and startRow and numRows. * It is up to you to pass the 'WHERE' in your where clausis. * * @param where the sql 'where' clause * @param startRow the start row to be used (first row = 1, last row = -1) * @param numRows the number of rows to be retrieved (all rows = a negative number) - * @param fieldList table of the field's associated constants * @return the resulting bean List */ - public List loadByWhere(String where, int[] fieldList, int startRow, int numRows) throws SQLException - { - String sql = null; - if (fieldList == null) { - sql = "SELECT " + getAllFields() + " FROM " + getTableName() + " " + where; - } else { - StringBuilder buff = new StringBuilder(); - buff.append("SELECT "); - for(int i = 0; i < fieldList.length; i++) { - if(i != 0) buff.append(","); - buff.append(getFieldNames()[fieldList[i]]); - } - buff.append(" FROM " + getTableName() + " "); - buff.append(where); - sql = buff.toString(); - buff = null; - } + public List loadByWhere(String where, int startRow, int numRows) throws SQLException { + StringBuilder sql = new StringBuilder(); + sql.append("SELECT ").append(getAllFields()).append(" FROM ").append(getTableName()).append(" ").append(where); Connection c = null; Statement st = null; ResultSet rs = null; @@ -176,15 +143,42 @@ public abstract class BaseManager implements DaoManager try { c = getConnection(); st = c.createStatement(); - rs = st.executeQuery(sql); - return decodeResultSet(rs, fieldList, startRow, numRows); + rs = st.executeQuery(sql.toString()); + return decodeResultSet(rs, startRow, numRows); } finally { - sql = null; close(st, rs); releaseConnection(c); } } + /** + * Retrieves a List of beans given a sql where clause and array of fields values + * + * @param where the sql 'where' clause + * @param fields object array of fields + * @return the resulting bean List + */ + public List loadByWhere(String where, Object... fields) throws SQLException { + StringBuilder sql = new StringBuilder(); + sql.append("SELECT ").append(getAllFields()).append(" FROM ").append(getTableName()).append(" ").append(where); + Connection c = null; + PreparedStatement ps = null; + ResultSet rs = null; + if (log.isTraceEnabled()) log.trace("loadByWhere: {}", sql); + try { + c = getConnection(); + ps = c.prepareStatement(sql.toString(), + ResultSet.TYPE_SCROLL_INSENSITIVE, + ResultSet.CONCUR_READ_ONLY); + fillPreparedStatement(ps, fields); + rs = ps.executeQuery(); + return decodeResultSet(rs, 1, -1); + } finally { + close(ps, rs); + releaseConnection(c); + } + } + /** * Retrieves the unique object given a sql 'where' clause. * @@ -200,6 +194,22 @@ public abstract class BaseManager implements DaoManager } } + /** + * Retrieves the unique object given a sql 'where' clause and a array of field values + * + * @param where The sql 'where' clause + * @param fields object array of fields + * @return The resulting bean + */ + public T loadUniqueByWhere(String where, Object... fields) throws SQLException { + List os = loadByWhere(where, fields); + if (os != null && os.size() > 0) { + return os.get(0); + } else { + return null; + } + } + /** * Deletes all rows from table. * @return the number of deleted rows. @@ -216,13 +226,12 @@ public abstract class BaseManager implements DaoManager * @param where the sql 'where' clause * @return the number of deleted rows */ - public int deleteByWhere(String where) throws SQLException - { + public int deleteByWhere(String where) throws SQLException { Connection c = null; PreparedStatement ps = null; try { c = getConnection(); - StringBuilder sql = new StringBuilder("DELETE FROM " + getTableName() + " " + where); + StringBuilder sql = new StringBuilder("DELETE FROM ").append(getTableName()).append(" ").append(where); if (log.isTraceEnabled()) log.trace("deleteByWhere: {}", sql); ps = c.prepareStatement(sql.toString()); return ps.executeUpdate(); @@ -232,6 +241,23 @@ public abstract class BaseManager implements DaoManager } } + public int deleteByWhere(String where, Object... fields) throws SQLException { + StringBuilder sql = new StringBuilder("DELETE FROM ").append(getTableName()).append(" ").append(where); + Connection c = null; + PreparedStatement ps = null; + if (log.isTraceEnabled()) log.trace("deleteByWhere: {}", sql); + try { + c = getConnection(); + ps = c.prepareStatement(sql.toString()); + fillPreparedStatement(ps, fields); + return ps.executeUpdate(); + } finally { + close(ps); + releaseConnection(c); + } + + } + /** * Saves the bean into the database. * @@ -273,9 +299,9 @@ public abstract class BaseManager implements DaoManager public abstract T insert(T bean, boolean orUpdate, boolean delayed) throws SQLException; /** - * Update the bean record in the database according to the changes. + * Update the $beanClass bean record in the database according to the changes. * - * @param bean the bean to be updated + * @param bean the $beanClass bean to be updated */ public abstract T update(T bean) throws SQLException; @@ -379,7 +405,7 @@ public abstract class BaseManager implements DaoManager scrollType, ResultSet.CONCUR_READ_ONLY); fillPreparedStatement(ps, bean, searchType); - return loadByPreparedStatement(ps, null, startRow, numRows); + return loadByPreparedStatement(ps, startRow, numRows); } finally { close(ps); releaseConnection(c); @@ -412,9 +438,8 @@ public abstract class BaseManager implements DaoManager * @param where the restriction clause * @return the number of rows returned */ - public int countWhere(String where) throws SQLException - { - String sql = "SELECT COUNT(*) AS MCOUNT FROM " + getTableName() + " " + where; + public int countWhere(String where) throws SQLException { + StringBuilder sql = new StringBuilder("SELECT COUNT(*) AS MCOUNT FROM ").append(getTableName()).append(" ").append(where); if (log.isTraceEnabled()) log.trace("countWhere: {}", sql); Connection c = null; Statement st = null; @@ -423,20 +448,47 @@ public abstract class BaseManager implements DaoManager int iReturn = -1; c = getConnection(); st = c.createStatement(); - rs = st.executeQuery(sql); + rs = st.executeQuery(sql.toString()); if (rs.next()) { iReturn = rs.getInt("MCOUNT"); } - if (iReturn != -1) - return iReturn; + if (iReturn != -1) return iReturn; } finally { close(st, rs); releaseConnection(c); - sql = null; } throw new SQLException("Error in countWhere"); } + /** + * Retrieves the number of rows of the table with a 'where' clause and a fields array. + * + * @param where the restriction clause + * @param fields object array of fields + * @return the number of rows returned + */ + public int countWhere(String where, Object... fields) throws SQLException { + StringBuilder sql = new StringBuilder("SELECT COUNT(*) AS MCOUNT FROM ").append(getTableName()).append(" ").append(where); + Connection c = null; + PreparedStatement ps = null; + ResultSet rs = null; + if (log.isTraceEnabled()) log.trace("countWhere: {}", sql); + try { + int iReturn = -1; + c = getConnection(); + ps = c.prepareStatement(sql.toString()); + fillPreparedStatement(ps, fields); + rs = ps.executeQuery(); + if (rs.next()) { + iReturn = rs.getInt("MCOUNT"); + } + if (iReturn != -1) return iReturn; + } finally { + close(ps, rs); + releaseConnection(c); + } + throw new SQLException("Error in countWhere"); + } /** * Count the number of elements of a specific bean @@ -518,26 +570,20 @@ public abstract class BaseManager implements DaoManager * Decode a ResultSet in a List of objects * * @param rs the resultset to decode - * @param fieldList table of the field's associated constants * @param startRow the start row to be used (first row = 1, last row = -1) * @param numRows the number of rows to be retrieved (all rows = a negative number) * @return the resulting bean List */ - public List decodeResultSet(ResultSet rs, int[] fieldList, int startRow, int numRows) throws SQLException { + public List decodeResultSet(ResultSet rs, int startRow, int numRows) throws SQLException { List v = new ArrayList(); int count = 0; - try { - if (rs.absolute(startRow) && numRows!=0) { - do { - if(fieldList == null) v.add(decodeRow(rs)); - else v.add(decodeRow(rs, fieldList)); - count++; - } while ( (count implements DaoManager */ public abstract T decodeRow(ResultSet rs) throws SQLException; - /** - * Transforms a ResultSet iterating on a bean according to a list of fields. - * - * @param rs the ResultSet to be transformed - * @param fieldList table of the field's associated constants - * @return bean resulting bean - */ - public abstract T decodeRow(ResultSet rs, int[] fieldList) throws SQLException; - /** * Transforms a ResultSet iterating on a bean using the names of the columns * @@ -572,145 +609,70 @@ public abstract class BaseManager implements DaoManager * @return a List of beans */ public List loadByPreparedStatement(PreparedStatement ps) throws SQLException { - return loadByPreparedStatement(ps, null); - } - - /** - * Loads all the elements using a prepared statement specifying a list of fields to be retrieved. - * - * @param ps the PreparedStatement to be used - * @param fieldList table of the field's associated constants - * @return a List of beans - */ - public List loadByPreparedStatement(PreparedStatement ps, int[] fieldList) throws SQLException { - return loadByPreparedStatement(ps, fieldList, 1, -1); + return loadByPreparedStatement(ps, 1, -1); } /** - * Loads all the elements using a prepared statement specifying a list of fields to be retrieved, - * and specifying the start row and the number of rows. + * Loads all the elements using a prepared statement specifying the start row and the number of rows. * * @param ps the PreparedStatement to be used * @param startRow the start row to be used (first row = 1, last row = -1) * @param numRows the number of rows to be retrieved (all rows = a negative number) - * @param fieldList table of the field's associated constants * @return a List of beans */ - public List loadByPreparedStatement(PreparedStatement ps, int[] fieldList, int startRow, int numRows) throws SQLException { + public List loadByPreparedStatement(PreparedStatement ps, int startRow, int numRows) throws SQLException { ResultSet rs = null; try { rs = ps.executeQuery(); - return decodeResultSet(rs, fieldList, startRow, numRows); + return decodeResultSet(rs, startRow, numRows); } finally { close(rs); } } /** - * fills the given stringbuffer with the sql where clausis constructed using the bean and the search type + * Fills the given StringBuilder with the sql where clausis constructed using the bean and the search type * @param sqlWhere the stringbuffer that will be filled * @param bean the bean to use for creating the where clausis * @param searchType exact ? like ? starting like ? - * @return the number of clausis returned + * @return the number of clause is returned */ protected abstract int fillWhere(StringBuilder sqlWhere, T bean, int searchType) throws SQLException; /** - * fill the given prepared statement with the bean values and a search type + * Fill the given PreparedStatement with the bean values and a search type * @param ps the preparedStatement that will be filled * @param bean the bean to use for creating the where clausis * @param searchType exact ? like ? starting like ? - * @return the number of clausis returned + * @return the number of clause is returned */ protected abstract int fillPreparedStatement(PreparedStatement ps, T bean, int searchType) throws SQLException; - - // UTILITIES - - - /** - * Notify Listener before INSERT, suppressing exceptions from the Listener - * @param bean the bean before INSERT - */ - protected void beforeInsert(T bean) { - if (listener != null) { - try { - listener.beforeInsert(bean); - } catch (Exception e) { - log.trace("Error notifying listener.beforeInsert: {}", e); - } - } - } - - /** - * Notify Listener after INSERT, suppressing exceptions from the Listener - * @param bean the bean after INSERT - */ - protected void afterInsert(T bean) { - if (listener != null) { - try { - listener.afterInsert(bean); - } catch (Exception e) { - log.trace("Error notifying listener.afterInsert: {}", e); - } - } - } - - /** - * Notify Listener before UPDATE, suppressing exceptions from the Listener - * @param bean the bean before UPDATE - */ - protected void beforeUpdate(T bean) { - if (listener != null) { - try { - listener.beforeUpdate(bean); - } catch (Exception e) { - log.trace("Error notifying listener.beforeUpdate: {}", e); - } - } - } - /** - * Notify Listener after UPDATE, suppressing exceptions from the Listener - * @param bean the bean after UPDATE - */ - protected void afterUpdate(T bean) { - if (listener != null) { - try { - listener.afterUpdate(bean); - } catch (Exception e) { - log.trace("Error notifying listener.afterUpdate: {}", e); - } - } - } - - /** - * Notify Listener before DELETE, suppressing exceptions from the Listener - * @param bean the bean before DELETE - */ - protected void beforeDelete(T bean) { - if (listener != null) { - try { - listener.beforeDelete(bean); - } catch (Exception e) { - log.trace("Error notifying listener.beforeDelete: {}", e); - } - } + * Fill the given PreparedStatement with the given fields + * @param ps the preparedStatement that will be filled + * @param fields the Object array of fields to be filled + * @return the number of fields filled + */ + protected int fillPreparedStatement(PreparedStatement ps, Object... fields) throws SQLException { + for (int i=0;i implements DaoManager // Helper methods for fetching numbers using IDs or names //////////////////////////////////////////////////// + //Date/Timestamp + //Byte + //Blob/Clob + /** * Retrieves an int value from the passed result set as an Integer object. */ - protected static Integer getInteger(ResultSet rs, int pos) throws SQLException { + public static Integer getInteger(ResultSet rs, int pos) throws SQLException { int i = rs.getInt(pos); return rs.wasNull() ? (Integer)null : new Integer(i); } @@ -781,7 +747,7 @@ public abstract class BaseManager implements DaoManager /** * Retrieves an int value from the passed result set as an Integer object. */ - protected static Integer getInteger(ResultSet rs, String column) throws SQLException { + public static Integer getInteger(ResultSet rs, String column) throws SQLException { int i = rs.getInt(column); return rs.wasNull() ? (Integer)null : new Integer(i); } @@ -789,21 +755,15 @@ public abstract class BaseManager implements DaoManager /** * Set an Integer object to the passed prepared statement as an int or as null. */ - protected static void setInteger(PreparedStatement ps, int pos, Integer i) throws SQLException { - if (i==null) - { - ps.setNull(pos, Types.INTEGER); - } - else - { - ps.setInt(pos, i.intValue()); - } + public static void setInteger(PreparedStatement ps, int pos, Integer i) throws SQLException { + if (i==null) ps.setNull(pos, Types.INTEGER); + else ps.setInt(pos, i.intValue()); } /** * Retrieves a float value from the passed result set as a Float object. */ - protected static Float getFloat(ResultSet rs, int pos) throws SQLException { + public static Float getFloat(ResultSet rs, int pos) throws SQLException { float f = rs.getFloat(pos); return rs.wasNull() ? (Float)null : new Float(f); } @@ -811,7 +771,7 @@ public abstract class BaseManager implements DaoManager /** * Retrieves a float value from the passed result set as a Float object. */ - protected static Float getFloat(ResultSet rs, String column) throws SQLException { + public static Float getFloat(ResultSet rs, String column) throws SQLException { float f = rs.getFloat(column); return rs.wasNull() ? (Float)null : new Float(f); } @@ -819,21 +779,15 @@ public abstract class BaseManager implements DaoManager /** * Set a Float object to the passed prepared statement as a float or as null. */ - protected static void setFloat(PreparedStatement ps, int pos, Float f) throws SQLException { - if (f==null) - { - ps.setNull(pos, Types.FLOAT); - } - else - { - ps.setFloat(pos, f.floatValue()); - } + public static void setFloat(PreparedStatement ps, int pos, Float f) throws SQLException { + if (f==null) ps.setNull(pos, Types.FLOAT); + else ps.setFloat(pos, f.floatValue()); } /** * Retrieves a double value from the passed result set as a Double object. */ - protected static Double getDouble(ResultSet rs, int pos) throws SQLException { + public static Double getDouble(ResultSet rs, int pos) throws SQLException { double d = rs.getDouble(pos); return rs.wasNull() ? (Double)null : new Double(d); } @@ -841,7 +795,7 @@ public abstract class BaseManager implements DaoManager /** * Retrieves a double value from the passed result set as a Double object. */ - protected static Double getDouble(ResultSet rs, String column) throws SQLException { + public static Double getDouble(ResultSet rs, String column) throws SQLException { double d = rs.getDouble(column); return rs.wasNull() ? (Double)null : new Double(d); } @@ -849,21 +803,15 @@ public abstract class BaseManager implements DaoManager /** * Set a Double object to the passed prepared statement as a double or as null. */ - protected static void setDouble(PreparedStatement ps, int pos, Double d) throws SQLException { - if (d==null) - { - ps.setNull(pos, Types.DOUBLE); - } - else - { - ps.setDouble(pos, d.doubleValue()); - } + public static void setDouble(PreparedStatement ps, int pos, Double d) throws SQLException { + if (d==null) ps.setNull(pos, Types.DOUBLE); + else ps.setDouble(pos, d.doubleValue()); } /** * Retrieves a long value from the passed result set as a Long object. */ - protected static Long getLong(ResultSet rs, int pos) throws SQLException { + public static Long getLong(ResultSet rs, int pos) throws SQLException { long l = rs.getLong(pos); return rs.wasNull() ? (Long)null : new Long(l); } @@ -871,7 +819,7 @@ public abstract class BaseManager implements DaoManager /** * Retrieves a long value from the passed result set as a Long object. */ - protected static Long getLong(ResultSet rs, String column) throws SQLException { + public static Long getLong(ResultSet rs, String column) throws SQLException { long l = rs.getLong(column); return rs.wasNull() ? (Long)null : new Long(l); } @@ -879,21 +827,15 @@ public abstract class BaseManager implements DaoManager /** * Set a Long object to the passed prepared statement as a long or as null. */ - protected static void setLong(PreparedStatement ps, int pos, Long l) throws SQLException { - if (l==null) - { - ps.setNull(pos, Types.BIGINT); - } - else - { - ps.setLong(pos, l.longValue()); - } + public static void setLong(PreparedStatement ps, int pos, Long l) throws SQLException { + if (l==null) ps.setNull(pos, Types.BIGINT); + else ps.setLong(pos, l.longValue()); } /** * Retrieves a boolean value from the passed result set as a Boolean object. */ - protected static Boolean getBoolean(ResultSet rs, int pos) throws SQLException { + public static Boolean getBoolean(ResultSet rs, int pos) throws SQLException { boolean b = rs.getBoolean(pos); return rs.wasNull() ? (Boolean)null : new Boolean(b); } @@ -901,7 +843,7 @@ public abstract class BaseManager implements DaoManager /** * Retrieves a boolean value from the passed result set as a Boolean object. */ - protected static Boolean getBoolean(ResultSet rs, String column) throws SQLException { + public static Boolean getBoolean(ResultSet rs, String column) throws SQLException { boolean b = rs.getBoolean(column); return rs.wasNull() ? (Boolean)null : new Boolean(b); } @@ -909,15 +851,9 @@ public abstract class BaseManager implements DaoManager /** * Set a Boolean object to the passed prepared statement as a boolean or as null. */ - protected static void setBoolean(PreparedStatement ps, int pos, Boolean b) throws SQLException { - if (b==null) - { - ps.setNull(pos, Types.BOOLEAN); - } - else - { - ps.setBoolean(pos, b.booleanValue()); - } + public static void setBoolean(PreparedStatement ps, int pos, Boolean b) throws SQLException { + if (b==null) ps.setNull(pos, Types.BOOLEAN); + else ps.setBoolean(pos, b.booleanValue()); } //////////////////////////////////////////////////// @@ -1085,36 +1021,26 @@ public abstract class BaseManager implements DaoManager "EEE dd, MMM yy" // ex: Wed 19, Feb 03 }; - /** * get a date from a date string representation in one of the registered formats * @param strDate the date as string. If (null or empty) or correct pattern was not found * @return Date object */ - static protected java.util.Date getDateFromString(String strDate) + static public java.util.Date getDateFromString(String strDate) { - if (strDate != null) - strDate = strDate.trim(); + if (strDate != null) strDate = strDate.trim(); SimpleDateFormat pSimpleDateFormat = new SimpleDateFormat(""); java.util.Date dReceivedDate = Calendar.getInstance().getTime(); - if (strDate != null && "".equals(strDate) == false) - { - for (int i=0; i implements DaoManager * @param strDate the date as string. * @return boolean "true" if the string represantes the date in one of the registed formats. */ - static protected boolean isDate(String strDate) + static public boolean isDate(String strDate) { if (strDate != null) strDate = strDate.trim(); SimpleDateFormat pSimpleDateFormat = new SimpleDateFormat(""); @@ -1138,7 +1064,7 @@ public abstract class BaseManager implements DaoManager java.util.Date dReceivedDate = pSimpleDateFormat.parse(strDate); if (dReceivedDate == null) continue; return true; - } catch (java.text.ParseException pe) { + } catch (ParseException pe) { // ignore as it is reported below } } diff --git a/src/main/resources/templates/velocity/table/bean.java.vm b/src/main/resources/bean.java.vm similarity index 100% rename from src/main/resources/templates/velocity/table/bean.java.vm rename to src/main/resources/bean.java.vm diff --git a/src/main/resources/templates/velocity/global/daobean.java.vm b/src/main/resources/daobean.java.vm similarity index 100% rename from src/main/resources/templates/velocity/global/daobean.java.vm rename to src/main/resources/daobean.java.vm diff --git a/src/main/resources/templates/velocity/global/daomanager.java.vm b/src/main/resources/daomanager.java.vm similarity index 81% rename from src/main/resources/templates/velocity/global/daomanager.java.vm rename to src/main/resources/daomanager.java.vm index c602764..d9880c0 100755 --- a/src/main/resources/templates/velocity/global/daomanager.java.vm +++ b/src/main/resources/daomanager.java.vm @@ -20,11 +20,13 @@ public interface DaoManager public List loadAll() throws SQLException; public List loadAll(int startRow, int numRows) throws SQLException; public List loadByWhere(String where) throws SQLException; - public List loadByWhere(String where, int[] fieldList) throws SQLException; - public List loadByWhere(String where, int[] fieldList, int startRow, int numRows) throws SQLException; + public List loadByWhere(String where, Object... fields) throws SQLException; + public List loadByWhere(String where, int startRow, int numRows) throws SQLException; public T loadUniqueByWhere(String where) throws SQLException; + public T loadUniqueByWhere(String where, Object... fields) throws SQLException; public int deleteAll() throws SQLException; public int deleteByWhere(String where) throws SQLException; + public int deleteByWhere(String where, Object... fields) throws SQLException; public T save(T bean) throws SQLException; public T insert(T bean) throws SQLException; public T insert(T bean, boolean orUpdate) throws SQLException; @@ -40,14 +42,13 @@ public interface DaoManager public int deleteUsingTemplate(T bean) throws SQLException; public int countAll() throws SQLException; public int countWhere(String where) throws SQLException; + public int countWhere(String where, Object... fields) throws SQLException; public int countUsingTemplate(T bean) throws SQLException; public int countUsingTemplate(T bean, int startRow, int numRows) throws SQLException; public int countUsingTemplate(T bean, int startRow, int numRows, int searchType) throws SQLException; - public List decodeResultSet(ResultSet rs, int[] fieldList, int startRow, int numRows) throws SQLException; + public List decodeResultSet(ResultSet rs, int startRow, int numRows) throws SQLException; public T decodeRow(ResultSet rs) throws SQLException; - public T decodeRow(ResultSet rs, int[] fieldList) throws SQLException; public T metaDataDecodeRow(ResultSet rs) throws SQLException; public List loadByPreparedStatement(PreparedStatement ps) throws SQLException; - public List loadByPreparedStatement(PreparedStatement ps, int[] fieldList) throws SQLException; - public List loadByPreparedStatement(PreparedStatement ps, int[] fieldList, int startRow, int numRows) throws SQLException; + public List loadByPreparedStatement(PreparedStatement ps, int startRow, int numRows) throws SQLException; } diff --git a/src/main/resources/templates/velocity/includes/header.include.vm b/src/main/resources/header.include.vm similarity index 100% rename from src/main/resources/templates/velocity/includes/header.include.vm rename to src/main/resources/header.include.vm diff --git a/src/main/resources/templates/velocity/table/manager.java.vm b/src/main/resources/manager.java.vm similarity index 89% rename from src/main/resources/templates/velocity/table/manager.java.vm rename to src/main/resources/manager.java.vm index c6b5ccc..03526c6 100644 --- a/src/main/resources/templates/velocity/table/manager.java.vm +++ b/src/main/resources/manager.java.vm @@ -153,14 +153,12 @@ public class $managerClass extends BaseManager<$beanClass> * @return a unique $beanClass */ //1 - public $beanClass loadByPrimaryKey($keys) throws SQLException - { + public $beanClass loadByPrimaryKey($keys) throws SQLException { Connection c = null; PreparedStatement ps = null; - try - { + try { c = getConnection(); - StringBuilder sql = new StringBuilder("SELECT " + ALL_FIELDS + " FROM $tablename WHERE $sql"); + StringBuilder sql = new StringBuilder("SELECT ").append(ALL_FIELDS).append(" FROM $tablename WHERE $sql"); if (log.isTraceEnabled()) log.trace("loadByPrimaryKey: {}", sql); ps = c.prepareStatement(sql.toString(), ResultSet.TYPE_SCROLL_INSENSITIVE, @@ -169,13 +167,9 @@ public class $managerClass extends BaseManager<$beanClass> $pk.getPreparedStatementMethod($strUtil.getVarName($pk), $velocityCount) #end List<$beanClass> pReturn = loadByPreparedStatement(ps); - if (pReturn.size() < 1) - return null; - else - return pReturn.get(0); - } - finally - { + if (pReturn.size() < 1) return null; + else return pReturn.get(0); + } finally { close(ps); releaseConnection(c); } @@ -192,12 +186,10 @@ public class $managerClass extends BaseManager<$beanClass> * @return the number of deleted rows */ //2 - public int deleteByPrimaryKey($keys) throws SQLException - { + public int deleteByPrimaryKey($keys) throws SQLException { Connection c = null; PreparedStatement ps = null; - try - { + try { c = getConnection(); StringBuilder sql = new StringBuilder("DELETE FROM $tablename WHERE $sql"); if (log.isTraceEnabled()) log.trace("loadByPrimaryKey: {}", sql); @@ -208,9 +200,7 @@ public class $managerClass extends BaseManager<$beanClass> $pk.getPreparedStatementMethod($strUtil.getVarName($pk), $velocityCount) #end return ps.executeUpdate(); - } - finally - { + } finally { close(ps); releaseConnection(c); } @@ -240,8 +230,7 @@ public class $managerClass extends BaseManager<$beanClass> * @return the associated $importedClass bean */ //3 GET IMPORTED - public $importedClass[] get${importedClass}s($beanClass bean) throws SQLException - { + public $importedClass[] get${importedClass}s($beanClass bean) throws SQLException { $importedClass other = ${importedClassManager}.getInstance().create${importedClass}(); other.${strUtil.getSetMethod($impKey.getForeignColumn())}(bean.${strUtil.getGetMethod($impKey)}()); return ${importedClassManager}.getInstance().loadUsingTemplate(other); @@ -276,8 +265,7 @@ public class $managerClass extends BaseManager<$beanClass> * @param delayed use INSERT DELAYED and don't get generated keys */ //13 - public $beanClass insert($beanClass bean, boolean orUpdate, boolean delayed) throws SQLException - { + public $beanClass insert($beanClass bean, boolean orUpdate, boolean delayed) throws SQLException { // mini checks if (!bean.isModified()) { return bean; // should not we log something ? @@ -285,35 +273,28 @@ public class $managerClass extends BaseManager<$beanClass> if (!bean.isNew()){ return update(bean); } - Connection c = null; PreparedStatement ps = null; StringBuilder sql = null; - - try - { + try { c = getConnection(); ##-------------writePreInsert #set( $genKeyRetrieve = $codewriter.getProperty("generatedkey.retrieve", "") ) #set ( $hint = $codewriter.getProperty("generatedkey.statement").replaceAll("
", $tablename) ) #if ( $primaryKeys.size() > 0 )#set ( $pKey = $primaryKeys.get(0) )#end #if ( $genKeyRetrieve == "before" && $primaryKeys.size() == 1 && $pKey.isColumnNumeric() ) - if (!bean.$strUtil.getModifiedMethod($pKey)()) - { + if (!bean.$strUtil.getModifiedMethod($pKey)()) { StringBuilder hint = new StringBuilder("$hint"); if (log.isTraceEnabled()) log.trace("generatedKey : {}", hint); ps = c.prepareStatement(hint.toString()); ResultSet rs = null; - try - { + try { rs = ps.executeQuery(); if(rs.next()) bean.$strUtil.getSetMethod($pKey)($pKey.getResultSetMethodObject("1")); else log.warn("Could not retrieve generated key"); - } - finally - { + } finally { close(ps, rs); ps=null; } @@ -386,8 +367,7 @@ public class $managerClass extends BaseManager<$beanClass> #set ( $hint = $codewriter.getProperty("generatedkey.statement").replaceAll("
", $tablename) ) #if ( $genKeyRetrieve == "after" ) - if (!bean.$strUtil.getModifiedMethod($pKey)()) - { + if (!bean.$strUtil.getModifiedMethod($pKey)()) { PreparedStatement ps2 = null; ResultSet rs = null; try { @@ -403,8 +383,7 @@ public class $managerClass extends BaseManager<$beanClass> } } #elseif ( $genKeyRetrieve == "auto" ) - if (!bean.$strUtil.getModifiedMethod($pKey)() && !delayed) - { + if (!bean.$strUtil.getModifiedMethod($pKey)() && !delayed) { ResultSet rs = ps.getGeneratedKeys(); try { if(rs.next()) @@ -423,10 +402,7 @@ public class $managerClass extends BaseManager<$beanClass> bean.isNew(false); bean.resetIsModified(); return bean; - } - finally - { - sql = null; + } finally { close(ps); releaseConnection(c); } @@ -438,8 +414,7 @@ public class $managerClass extends BaseManager<$beanClass> * @param bean the $beanClass bean to be updated */ //14 - public $beanClass update($beanClass bean) throws SQLException - { + public $beanClass update($beanClass bean) throws SQLException { // mini checks if (!bean.isModified()) { return bean; // should not we log something ? @@ -447,13 +422,10 @@ public class $managerClass extends BaseManager<$beanClass> if (bean.isNew()){ return save(bean); } - Connection c = null; PreparedStatement ps = null; StringBuilder sql = null; - - try - { + try { c = getConnection(); #if ( $primaryKeys.size() == 0 ) @@ -519,10 +491,7 @@ $codewriter.log(" WARN : $tablename does not have any primary key...") bean.resetIsModified(); return bean; - } - finally - { - sql = null; + } finally { close(ps); releaseConnection(c); } @@ -540,8 +509,7 @@ $codewriter.log(" WARN : $tablename does not have any primary key...") * @return the number of deleted objects */ //21 - public int deleteUsingTemplate($beanClass bean) throws SQLException - { + public int deleteUsingTemplate($beanClass bean) throws SQLException { #if ( $primaryKeys.size() == 1) if (bean.$strUtil.getInitializedMethod($primaryKeys.get(0))()) return deleteByPrimaryKey(bean.$strUtil.getGetMethod($primaryKeys.get(0))()); @@ -552,8 +520,7 @@ $codewriter.log(" WARN : $tablename does not have any primary key...") StringBuilder sql = new StringBuilder("DELETE FROM $tablename ");; StringBuilder sqlWhere = new StringBuilder(""); - try - { + try { if (fillWhere(sqlWhere, bean, SEARCH_EXACT) == 0) { if (log.isTraceEnabled()) log.trace("The bean to look is not initialized... deleting all"); } else { @@ -569,13 +536,9 @@ $codewriter.log(" WARN : $tablename does not have any primary key...") int _rows = ps.executeUpdate(); return _rows; - } - finally - { + } finally { close(ps); releaseConnection(c); - sql = null; - sqlWhere = null; } } @@ -586,8 +549,7 @@ $codewriter.log(" WARN : $tablename does not have any primary key...") * @param searchType exact ? like ? starting like ? * @return the number of clausis returned */ - protected int fillWhere(StringBuilder sqlWhere, $beanClass bean, int searchType) throws SQLException - { + protected int fillWhere(StringBuilder sqlWhere, $beanClass bean, int searchType) throws SQLException { if (bean == null) return 0; int _dirtyCount = 0; @@ -595,24 +557,16 @@ $codewriter.log(" WARN : $tablename does not have any primary key...") StringBuilder sqlOperation = new StringBuilder("="); if (searchType != SEARCH_EXACT) sqlOperation = new StringBuilder(" like "); - try - { #foreach( $column in $columns ) - if (bean.$strUtil.getModifiedMethod($column)()) { - _dirtyCount ++; + if (bean.$strUtil.getModifiedMethod($column)()) { + _dirtyCount ++; #if ($column.isString()) - sqlWhere.append((sqlWhere.length() == 0) ? " " : " AND ").append("$column.getName() ").append(sqlOperation).append("?"); + sqlWhere.append((sqlWhere.length() == 0) ? " " : " AND ").append("$column.getName() ").append(sqlOperation).append("?"); #else - sqlWhere.append((sqlWhere.length() == 0) ? " " : " AND ").append("$column.getName() ").append(sqlEqualsOperation).append("?"); -#end - } + sqlWhere.append((sqlWhere.length() == 0) ? " " : " AND ").append("$column.getName() ").append(sqlEqualsOperation).append("?"); #end } - finally - { - sqlEqualsOperation = null; - sqlOperation = null; - } +#end return _dirtyCount; } @@ -623,8 +577,7 @@ $codewriter.log(" WARN : $tablename does not have any primary key...") * @param searchType exact ? like ? starting like ? * @return the number of clausis returned */ - protected int fillPreparedStatement(PreparedStatement ps, $beanClass bean, int searchType) throws SQLException - { + protected int fillPreparedStatement(PreparedStatement ps, $beanClass bean, int searchType) throws SQLException { if (bean == null) return 0; int _dirtyCount = 0; @@ -664,49 +617,15 @@ $codewriter.log(" WARN : $tablename does not have any primary key...") * @param rs the ResultSet to be transformed * @return bean resulting $beanClass bean */ - //29 - public $beanClass decodeRow(ResultSet rs) throws SQLException - { + public $beanClass decodeRow(ResultSet rs) throws SQLException { $beanClass bean = create$beanClass(); ## the set statement casts $velocityCount to a string #foreach ( $column in $columns ) #set ($vCount = "$velocityCount" ) bean.$strUtil.getSetMethod($column)($column.getResultSetMethodObject($vCount)); #end - bean.isNew(false); bean.resetIsModified(); - - return bean; - } - - /** - * Transforms a ResultSet iterating on the $tablename table on a $beanClass bean according to a list of fields. - * - * @param rs the ResultSet to be transformed - * @param fieldList table of the field's associated constants - * @return bean resulting $beanClass bean - */ - //30 - public $beanClass decodeRow(ResultSet rs, int[] fieldList) throws SQLException - { - $beanClass bean = create$beanClass(); - int pos = 0; - for(int i = 0; i < fieldList.length; i++) - { - switch(fieldList[i]) - { -#foreach( $column in $columns ) - case ID_$column.getConstName(): - ++pos; - bean.$strUtil.getSetMethod($column)($column.getResultSetMethodObject("pos")); - break; -#end - } - } - bean.isNew(false); - bean.resetIsModified(); - return bean; } @@ -716,17 +635,13 @@ $codewriter.log(" WARN : $tablename does not have any primary key...") * @param rs the ResultSet to be transformed * @return bean resulting $beanClass bean */ - //31 - public $beanClass metaDataDecodeRow(ResultSet rs) throws SQLException - { + public $beanClass metaDataDecodeRow(ResultSet rs) throws SQLException { $beanClass bean = create$beanClass(); #foreach ( $column in $columns ) bean.$strUtil.getSetMethod($column)($column.getResultSetMethodObject("${Q}$column.getName()${Q}")); #end - bean.isNew(false); bean.resetIsModified(); - return bean; } diff --git a/src/main/resources/templates/velocity/includes/table.variables.include.vm b/src/main/resources/table.variables.include.vm similarity index 100% rename from src/main/resources/templates/velocity/includes/table.variables.include.vm rename to src/main/resources/table.variables.include.vm diff --git a/src/main/resources/templates/velocity/global/baselistener.java.vm b/src/main/resources/templates/velocity/global/baselistener.java.vm deleted file mode 100644 index de0c58a..0000000 --- a/src/main/resources/templates/velocity/global/baselistener.java.vm +++ /dev/null @@ -1,71 +0,0 @@ -##$Id: listener.java.vm,v 1.1 2005/10/12 12:37:58 framiere Exp $ -#parse( "header.include.vm" ) -$codewriter.setCurrentJavaFilename($pkg, "BaseListener.java") -package $pkg; - -import $pkg.*; - -/** - * No-op implementation of Listener as a convenience for implementing classes. - */ -public abstract class BaseListener implements Listener -{ - /** - * Invoked just before inserting a record into the database. - * - * @param bean the bean that is about to be inserted - */ - public void beforeInsert(T bean) { - - } - - /** - * Invoked just after a record is inserted in the database. - * - * @param bean the bean that was just inserted - */ - public void afterInsert(T bean) { - - } - - - /** - * Invoked just before updating a record in the database. - * - * @param bean the bean that is about to be updated - */ - public void beforeUpdate(T bean) { - - } - - - /** - * Invoked just after updating a record in the database. - * - * @param bean the bean that was just updated - */ - public void afterUpdate(T bean) { - - } - - - /** - * Invoked just before deleting a record in the database. - * - * @param bean the bean that is about to be deleted - */ - public void beforeDelete(T bean) { - - } - - - /** - * Invoked just after deleting a record in the database. - * - * @param bean the bean that was just deleted - */ - public void afterDelete(T bean) { - - } - -} diff --git a/src/main/resources/templates/velocity/global/cachingmanager.java.vm b/src/main/resources/templates/velocity/global/cachingmanager.java.vm deleted file mode 100755 index d338a78..0000000 --- a/src/main/resources/templates/velocity/global/cachingmanager.java.vm +++ /dev/null @@ -1,114 +0,0 @@ -##$Id: global.manager.java.vm,v 1.3 2005/10/10 20:11:46 framiere Exp $ -#parse( "header.include.vm" ) -$codewriter.setCurrentJavaFilename($pkg, "CachingManager.java") -package $pkg; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Simple primary key caching manager for sql2java generated managers. - * This provides a simple read through cache for (mostly) read-only data - * sources. It wraps the loadByPrimaryKey and loadByWhere methods of the - * underlying sql2java managers, and uses the method parameters as the key. - * This also supports a simple expiry mechanism. - */ -public class CachingManager -{ - private static final Logger logger = LoggerFactory.getLogger(CachingManager.class); - - private static final long DEFAULT_EXPIRE = 3600000l; //1 hour - - public CachingManager(DaoManager manager) - { - this.manager = manager; - this.cache = new HashMap(); - this.expiration = DEFAULT_EXPIRE; - } - - public CachingManager(DaoManager manager, Map cache) - { - this.manager = manager; - this.cache = cache; - this.expiration = DEFAULT_EXPIRE; - } - - public CachingManager(DaoManager manager, Map cache, long expiration) - { - this.manager = manager; - this.cache = cache; - this.expiration = expiration; - } - - private DaoManager manager; - private Map cache; - private long expiration; - - /** - * Retrieves the bean via primary key. - * @param primaryKey The Integer primary key. - * @return The bean or null. - */ - public T get(Integer primaryKey) - { - CacheEntry entry = (CacheEntry)cache.get(primaryKey); - if (entry != null && entry.valid()) return (T)entry.getBean(); - try { - Object o = manager.loadByPrimaryKey(primaryKey); - if (o != null) { - cache.put(primaryKey, new CacheEntry(primaryKey, o, expiration)); - return (T)o; - } - } catch (Exception e) { - logger.error("Error loading bean from cache: ", e); - } - return null; - } - - /** - * Retrieves the bean via primary key. - * @param where The WHERE clause. - * @return The bean or null. - */ - public List get(String where) - { - CacheEntry entry = (CacheEntry)cache.get(where); - if (entry != null && entry.valid()) return (List)entry.getBean(); - try { - List o = manager.loadByWhere(where); - if (o != null) { - logger.trace("CACHE PUT: "+where); - cache.put(where, new CacheEntry(where, o, expiration)); - return o; - } - } catch (Exception e) { - logger.error("Error loading bean from cache: ", e); - } - return null; - } - - private class CacheEntry { - - public CacheEntry(Object key, Object value, long expiration) { - this.key = key; - this.value = value; - this.loaded = System.currentTimeMillis(); - this.expiration = expiration; - } - - private Object key; - private Object value; - public Object getBean() { return this.value; } - private long loaded; - private long expiration; - - public boolean valid() - { - return System.currentTimeMillis()-loaded < expiration; - } - } - -} diff --git a/src/main/resources/templates/velocity/global/listener.java.vm b/src/main/resources/templates/velocity/global/listener.java.vm deleted file mode 100755 index 96968e9..0000000 --- a/src/main/resources/templates/velocity/global/listener.java.vm +++ /dev/null @@ -1,55 +0,0 @@ -##$Id: listener.java.vm,v 1.1 2005/10/12 12:37:58 framiere Exp $ -#parse( "header.include.vm" ) -$codewriter.setCurrentJavaFilename($pkg, "Listener.java") -package $pkg; - -import $pkg.*; - -/** - * Listener that is notified of table changes. - */ -public interface Listener -{ - /** - * Invoked just before inserting a record into the database. - * - * @param bean the bean that is about to be inserted - */ - public void beforeInsert(T bean); - - /** - * Invoked just after a record is inserted in the database. - * - * @param bean the bean that was just inserted - */ - public void afterInsert(T bean); - - /** - * Invoked just before updating a record in the database. - * - * @param bean the bean that is about to be updated - */ - public void beforeUpdate(T bean); - - /** - * Invoked just after updating a record in the database. - * - * @param bean the bean that was just updated - */ - public void afterUpdate(T bean); - - /** - * Invoked just before deleting a record in the database. - * - * @param bean the bean that is about to be deleted - */ - public void beforeDelete(T bean); - - /** - * Invoked just after deleting a record in the database. - * - * @param bean the bean that was just deleted - */ - public void afterDelete(T bean); - -} diff --git a/src/main/resources/templates/velocity/global/managerfactory.java.vm b/src/main/resources/templates/velocity/global/managerfactory.java.vm deleted file mode 100644 index f005c02..0000000 --- a/src/main/resources/templates/velocity/global/managerfactory.java.vm +++ /dev/null @@ -1,29 +0,0 @@ -package com.pickstream.model.sports; - -import java.lang.reflect.Constructor; -import javax.sql.DataSource; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Factory for managers. - * @author garth - */ -public class ManagerFactory -{ - private static final Logger logger = LoggerFactory.getLogger(ManagerFactory.class); - - public ManagerFactory(DataSource dataSource) { - this.dataSource = dataSource; - } - - protected DataSource dataSource; - - public Object getManager(Class clazz) throws Exception { - logger.trace("Attempting to load Manager for {}.", clazz); - Constructor ctr = clazz.getConstructor(DataSource.class); - Object o = ctr.newInstance(dataSource); - return o; - } - -} diff --git a/src/main/resources/templates/velocity/table/comparator.java.vm b/src/main/resources/templates/velocity/table/comparator.java.vm deleted file mode 100755 index 8576280..0000000 --- a/src/main/resources/templates/velocity/table/comparator.java.vm +++ /dev/null @@ -1,104 +0,0 @@ -##$Id: comparator.java.vm,v 1.2 2005/10/10 20:11:48 framiere Exp $ -#parse( "header.include.vm" ) -#parse( "table.variables.include.vm" ) -$codewriter.setCurrentJavaFilename("$table.getPackage()", "${comparatorClass}.java") -package $table.getPackage(); - -import java.util.Comparator; - -import $pkg.*; - -/** - * Comparator class is used to sort the $beanClass objects. - */ -public class $comparatorClass implements Comparator -{ - /** - * Holds the field on which the comparison is performed. - */ - private int iType; - /** - * Value that will contain the information about the order of the sort: normal or reversal. - */ - private boolean bReverse; - - /** - * Constructor class for $comparatorClass. - *
- * Example: - *
- * Arrays.sort(pArray, new $comparatorClass(${coreClass}Manager.$columns.get(0).getConstName(), bReverse)); - * - * @param iType the field from which you want to sort - *
- * Possible values are: - *
    -#foreach( $column in $columns ) -#if ( $column.hasCompareTo() ) - *
  • ${managerClass}.ID_$column.getConstName() -#end -#end - *
- */ - public $comparatorClass(int iType) - { - this(iType, false); - } - - /** - * Constructor class for ${comparatorClass}. - *
- * Example: - *
- * Arrays.sort(pArray, new $comparatorClass(${coreClass}Manager.$columns.get(0).getConstName(), bReverse)); - * - * @param iType the field from which you want to sort. - *
- * Possible values are: - *
    -#foreach( $column in $columns ) - *
  • ${managerClass}.ID_$column.getConstName() -#end - *
- * - * @param bReverse set this value to true, if you want to reverse the sorting results - */ - public $comparatorClass(int iType, boolean bReverse) - { - this.iType = iType; - this.bReverse = bReverse; - } - - /** - * Implementation of the compare method. - */ - public int compare(Object pObj1, Object pObj2) - { - $beanClass b1 = ($beanClass)pObj1; - $beanClass b2 = ($beanClass)pObj2; - int iReturn = 0; - switch(iType) - { -## I need to add a try catch here?????? -#foreach( $column in $columns ) -#set ( $getMethod = $strUtil.getGetMethod( $column ) ) -#if ( $column.hasCompareTo() ) - case ${managerClass}.ID_$column.getConstName(): - if (b1.$getMethod() == null && b2.$getMethod() != null) { - iReturn = -1; - } else if (b1.$getMethod() == null && b2.$getMethod() == null) { - iReturn = 0; - } else if (b1.$getMethod() != null && b2.$getMethod() == null) { - iReturn = 1; - } else { - iReturn = b1.$getMethod().compareTo(b2.$getMethod()); - } - break; -#end -#end - default: - throw new IllegalArgumentException("Type passed for the field is not supported"); - } - - return bReverse ? (-1 * iReturn) : iReturn; - }} diff --git a/src/config/test.properties b/src/test/config/test.properties similarity index 92% rename from src/config/test.properties rename to src/test/config/test.properties index c99697b..5bfd789 100644 --- a/src/config/test.properties +++ b/src/test/config/test.properties @@ -82,16 +82,11 @@ mgrwriter.destdir=target/generated-sources # templates (you can generate java files, jsp, etc...) -mgrwriter.templates.loadingpath=target/classes/templates/velocity/global, \ - target/classes/templates/velocity/table, \ - target/classes/templates/velocity/includes +mgrwriter.templates.loadingpath= mgrwriter.templates.perschema= daobean.java.vm, \ daomanager.java.vm, \ - basemanager.java.vm, \ - listener.java.vm, \ - baselistener.java.vm, \ - cachingmanager.java.vm + basemanager.java.vm mgrwriter.templates.pertable= bean.java.vm, \ manager.java.vm From 5b5a1929d0e373f19ec49b2ab5d22868cecb150d Mon Sep 17 00:00:00 2001 From: garthpatil Date: Mon, 24 Sep 2012 18:01:18 -0700 Subject: [PATCH 07/11] removed old run.sh file --- run.sh | 3 --- 1 file changed, 3 deletions(-) delete mode 100755 run.sh diff --git a/run.sh b/run.sh deleted file mode 100755 index 37428a0..0000000 --- a/run.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash - -mvn -e exec:java -Dexec.classpathScope="runtime" -Dexec.mainClass="net.sourceforge.sql2java.Main" -Dexec.args="$1" From 36b92d114b587cb6beb26003f52b63c748c74aee Mon Sep 17 00:00:00 2001 From: garthpatil Date: Mon, 24 Sep 2012 19:46:06 -0700 Subject: [PATCH 08/11] added a (SchemaName)Database class for easy access to all generated managers. --- README.md | 8 +- .../net/sourceforge/sql2java/CodeWriter.java | 5 +- .../sourceforge/sql2java/StringUtilities.java | 161 ++++++------------ src/main/resources/database.java.vm | 33 ++++ src/main/resources/header.include.vm | 2 + src/test/config/test.properties | 3 +- 6 files changed, 93 insertions(+), 119 deletions(-) create mode 100644 src/main/resources/database.java.vm diff --git a/README.md b/README.md index dcab2c8..bb3c8a2 100644 --- a/README.md +++ b/README.md @@ -1,22 +1,24 @@ # sql2java # -This is a fork of an abandoned project on SourceForge by the same name . It is heavily modified from the original version. I started using this around 2005 as a quick & dirty way to generate Java beans and data access managers from a SQL database. I still use it, as I have found many ORM tools like Hibernate to be unweildy and more trouble than they're worth. Other things that looks interesting to me these days are JDBI which puts nice Java idioms on top of SQL and JDBC, ActiveJDBC which walks a nice line between JDBC and the active record pattern, and Ebean which is an ORM, but feels right. +This is a fork of an abandoned project on SourceForge by the same name . It is heavily modified from the original version. I started using this around 2005 as a quick & dirty way to generate Java beans and data access managers from a SQL database. I still use it, as I have found many ORM tools like Hibernate to be unweildy and more trouble than they're worth. Other things that look interesting to me these days are JDBI which puts nice Java idioms on top of SQL and JDBC, ActiveJDBC which walks a nice line between JDBC and the active record pattern, and Ebean which is an ORM, but feels right. This differs from the original project in the following ways: - Build uses Maven. Packaged as a Maven plugin. - No more web widgets or factories. Just beans and managers. - *Managers return Lists instead of arrays. - Manager class is gone. BaseManager now takes a DataSource directly. +- Generates a (SchemaName)Database.java factory with get*Manager() methods for all managers. Intended as an easy entry point to extend as your application's DAO. - Uses generics to make the code more concise (and requires Java 1.5) - Not sure if anything but MySQL and HSQL support works anymore. PostgreSQL did work a while ago, but haven't checked in a bit. To do in the future: +- Allow interfaces in globals that don't relate to the schema (DaoManager, BaseManager, DaoBean) to be skipped so they can be elsewhere in the user's project or in an imported runtime library. - Add an interface for a cache providing a few convenience methods on top of a *Manager: T get(Id), List get(List), List get(Key) - Provide a optional runtime library with cache implementations. - The CodeWriter and Database classes are messy and fragile. Port to use SchemaCrawler -- Generate a (SchemaName)Database.java factory with get*Manager() methods for all managers. This would be an easy entry point to extend as your applications DAO. - Transactions? - Do something with foreign key mappings that is sane against bad definitions? +- Move the properties defined in the file into the Maven plugin definition. ### Using: ### To try it out, copy src/test/config/test.properties into your project and edit to reflect your databases's properties. @@ -56,7 +58,7 @@ There is a log at target/velocity.log that will tell you if anything failed, and The Velocity templates used by the code generator are in src/main/resources. If you add a new template, you must specify it in your properties file under mgrwriter.templates.perschema or mgrwriter.templates.pertable. ### Dependencies: ### -- Runtime dependencies for the generated code are slf4j for logging, and whatever JDBC driver you need for your database. +Runtime dependencies for the generated code are slf4j for logging, and whatever JDBC driver you need for your database. ### Feedback: ### Please submit a pull request if you'd like to see something changed. diff --git a/src/main/java/net/sourceforge/sql2java/CodeWriter.java b/src/main/java/net/sourceforge/sql2java/CodeWriter.java index 7d7fd78..4c64ce1 100755 --- a/src/main/java/net/sourceforge/sql2java/CodeWriter.java +++ b/src/main/java/net/sourceforge/sql2java/CodeWriter.java @@ -23,8 +23,6 @@ public class CodeWriter { static protected Properties props; - public static String MGR_CLASS="Manager"; - protected static String dateClassName; protected static String timeClassName; protected static String timestampClassName; @@ -278,16 +276,19 @@ public void writeComponent(String templateName) throws Exception { try { template = Velocity.getTemplate(templateName); } catch (ResourceNotFoundException rnfe) { + rnfe.printStackTrace(); System.err.println( "Aborted writing component:" + templateName + (table!=null?(" for table:" + table.getName()):"") + " because Velocity could not find the resource." ); return; } catch (ParseErrorException pee) { + pee.printStackTrace(); System.err.println( "Aborted writing component:" + templateName + (table!=null?(" for table:" + table.getName()):"") + " because there was a parse error in the resource.\n" + pee.getLocalizedMessage() ); return; } catch (Exception e) { + e.printStackTrace(); System.err.println( "Aborted writing component:" + templateName + (table!=null?(" for table:" + table.getName()):"") + " there was an error initializing the template.\n" + e.getLocalizedMessage() ); diff --git a/src/main/java/net/sourceforge/sql2java/StringUtilities.java b/src/main/java/net/sourceforge/sql2java/StringUtilities.java index 5f1f5a2..6e4c98a 100755 --- a/src/main/java/net/sourceforge/sql2java/StringUtilities.java +++ b/src/main/java/net/sourceforge/sql2java/StringUtilities.java @@ -14,34 +14,27 @@ * */ public final class StringUtilities { - static private StringUtilities singleton = new StringUtilities(); - - // TODO: convert into velocity macros - static public final String PREFIX = ""; - static public final String BASE_SUFFIX = ""; - static public final String MANAGER_SUFFIX = "Manager"; - //static public final String BEAN_SUFFIX = "Bean"; - static public final String BEAN_SUFFIX = ""; - static public final String RELATIONNAL_BEAN_SUFFIX = "Relationnal_Bean"; - static public final String HIBERNATE_MANAGER_SUFFIX = "Hibernate_Manager"; - static public final String ITERATOR_SUFFIX = "Iterator"; - static public final String FACTORY_SUFFIX = "Factory"; - static public final String COMPARATOR_SUFFIX = "Comparator"; - static public final String HTTP_FACTORY_SUFFIX = "Http_Factory"; - static public final String LISTENER_SUFFIX = "Listener"; - static public final String RENDERER_SUFFIX = "Renderer"; - static public final String EXCEPTION_SUFFIX = "Exception"; - static public final String WIDGETFACTORY_SUFFIX = "Widget_Factory"; - static public final String WIDGET_SUFFIX = "Widget"; - - private StringUtilities () { } - - /** This is the default method for obtaining a StringUtilities instance. - * @return The shared instance - */ - static public synchronized StringUtilities getInstance() { - return singleton; - } + + static private StringUtilities singleton = new StringUtilities(); + + // TODO: convert into velocity macros + static public final String PREFIX = ""; + static public final String BASE_SUFFIX = ""; + static public final String MANAGER_SUFFIX = "Manager"; + static public final String BEAN_SUFFIX = ""; + static public final String RELATIONNAL_BEAN_SUFFIX = "Relationnal_Bean"; + static public final String ITERATOR_SUFFIX = "Iterator"; + static public final String FACTORY_SUFFIX = "Factory"; + static public final String EXCEPTION_SUFFIX = "Exception"; + + private StringUtilities () { } + + /** This is the default method for obtaining a StringUtilities instance. + * @return The shared instance + */ + static public synchronized StringUtilities getInstance() { + return singleton; + } public String getPackageAsPath(String pkg){ if (pkg == null) @@ -57,8 +50,8 @@ public String getPropertyTag(Column col){ return col.getPropertyTag(); } - // TODO: convert into velocity macros - public String convertClass(String table, String type) + // TODO: convert into velocity macros + public String convertClass(String table, String type) { String suffix = ""; String postfix = ""; @@ -109,46 +102,6 @@ public String getFactoryClass(String table) return convertClass(table, FACTORY_SUFFIX); } - public String getHttpFactoryClass(Table table) - { - return convertClass(table.getName(), HTTP_FACTORY_SUFFIX); - } - - public String getHttpFactoryClass(String table) - { - return convertClass(table, HTTP_FACTORY_SUFFIX); - } - - public String getListenerClass(Table table) - { - return convertClass(table.getName(), LISTENER_SUFFIX); - } - - public String getListenerClass(String table) - { - return convertClass(table, LISTENER_SUFFIX); - } - - public String getRendererClass(Table table) - { - return convertClass(table.getName(), RENDERER_SUFFIX); - } - - public String getRendererClass(String table) - { - return convertClass(table, RENDERER_SUFFIX); - } - - public String getWidgetFactoryClass(Table table) - { - return convertClass(table.getName(), WIDGETFACTORY_SUFFIX); - } - - public String getWidgetFactoryClass(String table) - { - return convertClass(table, WIDGETFACTORY_SUFFIX); - } - public String getExceptionClass(Table table) { return convertClass(table.getName(), EXCEPTION_SUFFIX); @@ -159,16 +112,6 @@ public String getExceptionClass(String table) return convertClass(table, EXCEPTION_SUFFIX); } - public String getWidgetClass(Table table) - { - return convertClass(table.getName(), WIDGET_SUFFIX); - } - - public String getWidgetClass(String table) - { - return convertClass(table, WIDGET_SUFFIX); - } - public String getIteratorClass(Table table) { return convertClass(table.getName(), ITERATOR_SUFFIX); @@ -189,24 +132,16 @@ public String getManagerClass(String table) return convertClass(table, MANAGER_SUFFIX); } - public String getHibernateManagerClass(Table table) - { - return convertClass(table.getName(), HIBERNATE_MANAGER_SUFFIX); - } - - public String getHibernateManagerClass(String table) - { - return convertClass(table, HIBERNATE_MANAGER_SUFFIX); - } - - public String getComparatorClass(Table table) + public String getManagerObjectName(Table table) { - return convertClass(table.getName(), COMPARATOR_SUFFIX); + return getManagerObjectName(table.getName()); } - public String getComparatorClass(String table) + public String getManagerObjectName(String table) { - return convertClass(table, COMPARATOR_SUFFIX); + String objName = convertClass(table, MANAGER_SUFFIX); + char f = Character.toLowerCase(objName.charAt(0)); + return Character.toString(f)+objName.substring(1); } public String getStringConvertionMethod(Column col){ @@ -395,25 +330,25 @@ public String getImportedKeyModifiedMethod(String col) { public String getJavaPrimaryType( Column c ) { try { - return c.getJavaPrimaryType(); + return c.getJavaPrimaryType(); } catch ( Exception e ) { - return null; + return null; } } - public String convertName(String name) { + public String convertName(String name) { return convertName(name, false); } - public String convertName(Column col) { + public String convertName(Column col) { return convertName(col.getName(), false); } - public String convertName(Table table) { + public String convertName(Table table) { return convertName(table.getName(), false); } - /** + /** * Converts name into a more Java-ish style name. * @author netkernel *
@@ -439,19 +374,19 @@ public static String convertName(String name, boolean wimpyCaps) { } return buffer.toString(); } -// ORIGINAL CONVERT STRING -// public static String convertName(String name, boolean wimpyCaps) { -// StringBuffer buffer = new StringBuffer(name.length()); -// char list[] = name.toLowerCase().toCharArray(); -// for(int i = 0; i < list.length; i++) { -// if(i == 0 && !wimpyCaps) { -// buffer.append(Character.toUpperCase(list[i])); -// } else if(list[i] == '_' && (i+1) < list.length && i != 0) { -// buffer.append(Character.toUpperCase(list[++i])); -// } else buffer.append(list[i]); -// } -// return buffer.toString(); -// } + // ORIGINAL CONVERT STRING + // public static String convertName(String name, boolean wimpyCaps) { + // StringBuffer buffer = new StringBuffer(name.length()); + // char list[] = name.toLowerCase().toCharArray(); + // for(int i = 0; i < list.length; i++) { + // if(i == 0 && !wimpyCaps) { + // buffer.append(Character.toUpperCase(list[i])); + // } else if(list[i] == '_' && (i+1) < list.length && i != 0) { + // buffer.append(Character.toUpperCase(list[++i])); + // } else buffer.append(list[i]); + // } + // return buffer.toString(); + // } private String escape(String s) { return isReserved(s) ? ("my_"+s) : s; diff --git a/src/main/resources/database.java.vm b/src/main/resources/database.java.vm new file mode 100644 index 0000000..4ae0616 --- /dev/null +++ b/src/main/resources/database.java.vm @@ -0,0 +1,33 @@ +##$Id: global.manager.java.vm,v 1.3 2005/10/10 20:11:46 framiere Exp $ +#parse( "header.include.vm" ) +#set( $className = $strUtil.convertName($schema) ) +$codewriter.setCurrentJavaFilename($pkg, "${className}Database.java") +package $pkg; + +import javax.sql.DataSource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +/** + * ${className}Database is a mapping of the $schema schema. +*/ +public class ${className}Database { + + public ${className}Database(DataSource dataSource) { + this.dataSource = dataSource; +#foreach ( $table in $tables ) + this.$strUtil.getManagerObjectName($table) = new $strUtil.getManagerClass($table)(dataSource); +#end + } + + protected DataSource dataSource; +#foreach ( $table in $tables ) + protected $strUtil.getManagerClass($table) $strUtil.getManagerObjectName($table); +#end + +#foreach ( $table in $tables ) + public $strUtil.getManagerClass($table) get$strUtil.getManagerClass($table)() { + return this.$strUtil.getManagerObjectName($table); + } + +#end +} \ No newline at end of file diff --git a/src/main/resources/header.include.vm b/src/main/resources/header.include.vm index 70dda68..b2dc05a 100755 --- a/src/main/resources/header.include.vm +++ b/src/main/resources/header.include.vm @@ -1,5 +1,7 @@ ##$Id: header.include.vm,v 1.5 2005/10/10 20:11:47 framiere Exp $ #set ( $db = $codewriter.db ) +#set ( $schema = $db.getSchema() ) +#set ( $tables = $db.getTables() ) #set ( $allPackages = $db.getAllPackages() ) #set ( $widgetPkg = "${pkg}.widget") #set ( $SPACE = " ") diff --git a/src/test/config/test.properties b/src/test/config/test.properties index 5bfd789..eacdb38 100644 --- a/src/test/config/test.properties +++ b/src/test/config/test.properties @@ -86,7 +86,8 @@ mgrwriter.templates.loadingpath= mgrwriter.templates.perschema= daobean.java.vm, \ daomanager.java.vm, \ - basemanager.java.vm + basemanager.java.vm, \ + database.java.vm mgrwriter.templates.pertable= bean.java.vm, \ manager.java.vm From 8eb3c8848fd4d702c6810935a41d9a8dd40f0550 Mon Sep 17 00:00:00 2001 From: garthpatil Date: Wed, 26 Sep 2012 11:54:29 -0700 Subject: [PATCH 09/11] cleaned up some type problems --- pom.xml | 13 +++++++++++++ .../java/net/sourceforge/sql2java/CodeWriter.java | 10 ++++++++-- .../java/net/sourceforge/sql2java/Database.java | 3 ++- src/main/resources/basemanager.java.vm | 4 ++-- src/main/resources/database.java.vm | 3 ++- 5 files changed, 27 insertions(+), 6 deletions(-) diff --git a/pom.xml b/pom.xml index 092f1d3..fdc3256 100644 --- a/pom.xml +++ b/pom.xml @@ -9,6 +9,16 @@ sql2java-maven-plugin + + + maven-compiler-plugin + 2.0.2 + + 1.5 + 1.5 + + + @@ -42,6 +52,9 @@ mysql mysql-connector-java [5.1,) + runtime diff --git a/src/main/java/net/sourceforge/sql2java/CodeWriter.java b/src/main/java/net/sourceforge/sql2java/CodeWriter.java index 4c64ce1..72db26e 100755 --- a/src/main/java/net/sourceforge/sql2java/CodeWriter.java +++ b/src/main/java/net/sourceforge/sql2java/CodeWriter.java @@ -249,9 +249,15 @@ public synchronized void process() throws Exception private void writeTable(Table table) throws Exception { - if (table.getColumns().length == 0) { + Column[] cs = table.getColumns(); + if (cs.length == 0) { return; - } + } else { + // System.out.println("Writing files for table "+table.getName()); + // for (Column c:cs) { + // System.out.println(c.toString()); + // } + } current_vc = new VelocityContext(vc); this.table = table; current_vc.put("table", table); diff --git a/src/main/java/net/sourceforge/sql2java/Database.java b/src/main/java/net/sourceforge/sql2java/Database.java index cf19638..487da6e 100755 --- a/src/main/java/net/sourceforge/sql2java/Database.java +++ b/src/main/java/net/sourceforge/sql2java/Database.java @@ -96,7 +96,8 @@ public void load() throws SQLException, ClassNotFoundException loadTables(); loadColumns(); loadPrimaryKeys(); - // loadImportedKeys(); + + // loadImportedKeys(); // loadManyToMany(); // loadIndexes(); // experimental } diff --git a/src/main/resources/basemanager.java.vm b/src/main/resources/basemanager.java.vm index 2ef73c0..2e93a38 100644 --- a/src/main/resources/basemanager.java.vm +++ b/src/main/resources/basemanager.java.vm @@ -299,9 +299,9 @@ public abstract class BaseManager implements DaoManager public abstract T insert(T bean, boolean orUpdate, boolean delayed) throws SQLException; /** - * Update the $beanClass bean record in the database according to the changes. + * Update the bean record in the database according to the changes. * - * @param bean the $beanClass bean to be updated + * @param bean the bean to be updated */ public abstract T update(T bean) throws SQLException; diff --git a/src/main/resources/database.java.vm b/src/main/resources/database.java.vm index 4ae0616..a39cd8b 100644 --- a/src/main/resources/database.java.vm +++ b/src/main/resources/database.java.vm @@ -7,9 +7,10 @@ package $pkg; import javax.sql.DataSource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; + /** * ${className}Database is a mapping of the $schema schema. -*/ + */ public class ${className}Database { public ${className}Database(DataSource dataSource) { From 6ba725a678f0e838e8bc2e4e77a0a11126c75f82 Mon Sep 17 00:00:00 2001 From: garthpatil Date: Wed, 26 Sep 2012 14:24:12 -0700 Subject: [PATCH 10/11] bad loadByWhere in BaseManager fixed --- src/main/resources/basemanager.java.vm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/basemanager.java.vm b/src/main/resources/basemanager.java.vm index 2e93a38..72ef16f 100644 --- a/src/main/resources/basemanager.java.vm +++ b/src/main/resources/basemanager.java.vm @@ -121,7 +121,7 @@ public abstract class BaseManager implements DaoManager * @return the resulting bean */ public List loadByWhere(String where) throws SQLException { - return loadByWhere(where, null, 1, -1); + return loadByWhere(where, 1, -1); } /** From 87d5a10295656fcb57e4ca3ea8354f35df303d1a Mon Sep 17 00:00:00 2001 From: garthpatil Date: Wed, 10 Oct 2012 16:16:42 -0700 Subject: [PATCH 11/11] log generated key errors to trace when delayed or orUpdate is true --- README.md | 2 +- pom.xml | 10 +++++++--- src/main/resources/manager.java.vm | 19 ++++++++++++------- 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index bb3c8a2..4f13ad6 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ To do in the future: - The CodeWriter and Database classes are messy and fragile. Port to use SchemaCrawler - Transactions? - Do something with foreign key mappings that is sane against bad definitions? -- Move the properties defined in the file into the Maven plugin definition. +- Move the properties defined in the file into the Maven plugin definition. Allow a list of tables to be specified for generation. ### Using: ### To try it out, copy src/test/config/test.properties into your project and edit to reflect your databases's properties. diff --git a/pom.xml b/pom.xml index fdc3256..685ed3f 100644 --- a/pom.xml +++ b/pom.xml @@ -9,6 +9,13 @@ sql2java-maven-plugin + + + org.apache.maven.wagon + wagon-webdav + 1.0-beta-2 + + maven-compiler-plugin @@ -52,9 +59,6 @@ mysql mysql-connector-java [5.1,) - runtime diff --git a/src/main/resources/manager.java.vm b/src/main/resources/manager.java.vm index 03526c6..ebdc6b9 100644 --- a/src/main/resources/manager.java.vm +++ b/src/main/resources/manager.java.vm @@ -290,10 +290,12 @@ public class $managerClass extends BaseManager<$beanClass> ResultSet rs = null; try { rs = ps.executeQuery(); - if(rs.next()) + if(rs.next()) { bean.$strUtil.getSetMethod($pKey)($pKey.getResultSetMethodObject("1")); - else - log.warn("Could not retrieve generated key"); + } else { + if (delayed || orUpdate) log.trace("Could not retrieve generated key"); + else log.warn("Could not retrieve generated key"); + } } finally { close(ps, rs); ps=null; @@ -376,7 +378,8 @@ public class $managerClass extends BaseManager<$beanClass> if(rs.next()) { bean.$strUtil.getSetMethod($pKey)($pKey.getResultSetMethodObject("1")); } else { - log.warn("Could not retrieve generated key"); + if (delayed || orUpdate) log.trace("Could not retrieve generated key"); + else log.warn("Could not retrieve generated key"); } } finally { close(ps2, rs); @@ -386,10 +389,12 @@ public class $managerClass extends BaseManager<$beanClass> if (!bean.$strUtil.getModifiedMethod($pKey)() && !delayed) { ResultSet rs = ps.getGeneratedKeys(); try { - if(rs.next()) + if(rs.next()) { bean.$strUtil.getSetMethod($pKey)($pKey.getResultSetMethodObject("1")); - else - log.warn("Could not retrieve auto generated key"); + } else { + if (delayed || orUpdate) log.trace("Could not retrieve generated key"); + else log.warn("Could not retrieve generated key"); + } } finally { close(rs); }