├── .gitignore ├── README.md ├── pom.xml ├── sql2java-lib ├── pom.xml └── src │ └── main │ └── java │ └── net │ └── sourceforge │ └── sql2java │ └── lib │ ├── BaseManager.java │ ├── DaoBean.java │ ├── DaoManager.java │ ├── Database.java │ └── Txn.java ├── sql2java-maven-plugin ├── pom.xml └── src │ ├── main │ ├── java │ │ └── net │ │ │ └── sourceforge │ │ │ └── sql2java │ │ │ ├── CodeWriter.java │ │ │ ├── Column.java │ │ │ ├── Database.java │ │ │ ├── Main.java │ │ │ ├── StringUtilities.java │ │ │ ├── Table.java │ │ │ ├── UserCodeParser.java │ │ │ ├── ant │ │ │ ├── GenerationTask.java │ │ │ ├── SchemaCheckTask.java │ │ │ ├── TableGenerationTask.java │ │ │ └── UtilsGenerationTask.java │ │ │ └── maven │ │ │ ├── AbstractDbMojo.java │ │ │ ├── Sql2JavaMojo.java │ │ │ └── SqlFileMojo.java │ └── resources │ │ ├── basemanager.java.vm │ │ ├── bean.java.vm │ │ ├── daobean.java.vm │ │ ├── daomanager.java.vm │ │ ├── database.java.vm │ │ ├── header.include.vm │ │ ├── manager.java.vm │ │ └── table.variables.include.vm │ └── test │ └── config │ └── test.properties └── sql2java-test ├── README ├── pom.xml └── src ├── main ├── resources │ ├── sql2java.properties │ └── sqltool.rc └── sql │ ├── 00-test.sql │ └── 01-test.sql └── test ├── java └── com │ └── test │ └── TransactionTest.java └── resources └── sqltool.rc /.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | *~ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # sql2java # 2 | 3 | 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. 4 | 5 | This differs from the original project in the following ways: 6 | - Build uses Maven. Packaged as a Maven plugin. sql2java-maven-plugin and sql2java-lib are in Maven Central. 7 | - New Maven plugin (sqlfile) for sourcing a SQL DDL before generation. 8 | - sql2java-lib runtime library is now a mandatory dependency. 9 | - No more web widgets or factories. Just beans and managers. 10 | - *Managers return Lists instead of arrays. 11 | - Manager class is gone. BaseManager now takes a DataSource directly. 12 | - 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. 13 | - Management of transactions from the (SchemaName)Database.java class. 14 | - Uses generics to make the code more concise (and requires Java 1.5) 15 | - Not sure if anything but MySQL and HSQL support works anymore. PostgreSQL did work a while ago, but haven't checked in a bit. 16 | 17 | To do in the future: 18 | - 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). Add optional runtime library with cache implementations. 19 | - The CodeWriter and Database classes are messy and fragile. Port to use SchemaCrawler . Also look at jOOQ and see what they're doing. 20 | - Do something with foreign key mappings that is sane against bad definitions. 21 | - Do something better with compound primary keys (despite thinking they're a bad design decision). 22 | - Move the properties defined in the file into the Maven plugin definition. Allow a list of tables to be specified for generation. 23 | 24 | ### Using the generator: ### 25 | Easiest way to try it out is to copy the structure in sql2java-test/. 26 | 27 | Add the following to your POM file's build section: 28 | 29 | 30 | 31 | 32 | com.github.xgp 33 | sql2java-maven-plugin 34 | ${sql2java.version} 35 | 36 | 37 | sql2java 38 | 39 | sql2java 40 | 41 | 42 | 43 | 44 | ${project.build.directory}/generated-sources/sql2java 45 | ${project.basedir}/src/main/resources/sql2java.properties 46 | org.hsqldb.jdbc.JDBCDriver 47 | jdbc:hsqldb:file:${project.build.directory}/databases/test 48 | SA 49 | 50 | PUBLIC 51 | com.test 52 | 53 | 54 | 55 | 56 | org.hsqldb 57 | hsqldb 58 | ${hsqldb.version} 59 | 60 | 61 | 62 | 63 | 64 | 65 | And run: 66 | 67 | mvn sql2java:sql2java compile 68 | 69 | 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. 70 | 71 | ### Using the generated code: ### 72 | Given the schema example in sql2java-test/src/main/sql/00-test.sql: 73 | 74 | // Create a Database from your DataSource 75 | PublicDatabase db = new PublicDatabase(ds); 76 | 77 | // Transactionally create some rows 78 | try { 79 | db.beginTransaction(Txn.Isolation.REPEATABLE_READ); 80 | Person s0 = db.createBean(Person.class); 81 | s0.setUsername("hansolo"); 82 | s0.setFirstName("Harrison"); 83 | s0.setLastName("Ford"); 84 | s0.setCreateDate(new Date()); 85 | s0 = db.save(s0); 86 | Phone m0 = db.createBean(Phone.class); 87 | m0.setPersonId(s0.getId()); 88 | m0.setPhoneType(1); 89 | m0.setPhoneNumber("+14105551212"); 90 | m0.setCreateDate(new Date()); 91 | m0 = db.save(m0); 92 | db.commitTransaction(); 93 | } finally { 94 | db.endTransaction(); 95 | } 96 | 97 | // Find the rows 98 | Person s1 = db.loadUniqueByWhere(Person.class, "WHERE USERNAME='hansolo'"); 99 | Phone m1 = db.loadUniqueByWhere(Phone.class, "WHERE PHONE_NUMBER='+14105551212'"); 100 | 101 | // Delete the rows (auto-commit) 102 | db.deleteByWhere(Phone.class, "WHERE PHONE_NUMBER='+14105551212'"); 103 | db.deleteByWhere(Person.class, "WHERE USERNAME='hansolo'"); 104 | 105 | ### Customizing: ### 106 | 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. 107 | 108 | ### Dependencies: ### 109 | Runtime dependencies for the generated code are sql2java-lib, slf4j for logging, and whatever JDBC driver you need for your database. 110 | 111 | ### Feedback: ### 112 | Please submit a pull request if you'd like to see something changed. 113 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | com.github.xgp 5 | sql2java 6 | pom 7 | 0.9.1-SNAPSHOT 8 | sql2java 9 | sql2java code generator 10 | https://github.com/xgp/sql2java 11 | 12 | 13 | com.github.xgp 14 | oss-parent 15 | 0.1 16 | 17 | 18 | 19 | UTF-8 20 | UTF-8 21 | 1.5 22 | 2.3.4 23 | 1.7.22 24 | 25 | 26 | 27 | https://github.com/xgp/sql2java 28 | scm:git:git://github.com/xgp/sql2java.git 29 | scm:git:git@github.com:xgp/sql2java.git 30 | master 31 | 32 | 33 | 34 | 35 | GNU Library General Public License version 2.0 (LGPLv2) 36 | https://www.gnu.org/licenses/lgpl-2.0.txt 37 | 38 | 39 | 40 | 41 | 42 | Garth 43 | https://github.com/xgp 44 | 45 | 46 | 47 | 48 | sql2java-lib 49 | sql2java-maven-plugin 50 | 51 | 52 | 53 | 54 | 55 | org.slf4j 56 | slf4j-api 57 | ${slf4j.version} 58 | 59 | 60 | org.slf4j 61 | slf4j-simple 62 | ${slf4j.version} 63 | 64 | 65 | org.hsqldb 66 | hsqldb 67 | ${hsqldb.version} 68 | 69 | 70 | org.hsqldb 71 | sqltool 72 | ${hsqldb.version} 73 | 74 | 75 | junit 76 | junit 77 | 4.12 78 | 79 | 80 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /sql2java-lib/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | com.github.xgp 5 | sql2java-lib 6 | jar 7 | sql2java-lib 8 | 9 | 10 | com.github.xgp 11 | sql2java 12 | 0.9.1-SNAPSHOT 13 | 14 | 15 | 16 | 17 | org.slf4j 18 | slf4j-api 19 | compile 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /sql2java-lib/src/main/java/net/sourceforge/sql2java/lib/DaoBean.java: -------------------------------------------------------------------------------- 1 | package net.sourceforge.sql2java.lib; 2 | 3 | import java.util.Map; 4 | 5 | /** 6 | * Base interface that is implemented by generated beans. 7 | */ 8 | public interface DaoBean { 9 | public boolean isNew(); 10 | public boolean isModified(); 11 | public void resetIsModified(); 12 | public Map getDictionary(); 13 | public Map getPkDictionary(); 14 | public String toString(String delim); 15 | } 16 | -------------------------------------------------------------------------------- /sql2java-lib/src/main/java/net/sourceforge/sql2java/lib/DaoManager.java: -------------------------------------------------------------------------------- 1 | package net.sourceforge.sql2java.lib; 2 | 3 | import java.sql.PreparedStatement; 4 | import java.sql.ResultSet; 5 | import java.sql.SQLException; 6 | import java.util.List; 7 | 8 | /** 9 | * Data access manager. 10 | */ 11 | public interface DaoManager { 12 | public T createBean(); 13 | public String getTableName(); 14 | public T loadByPrimaryKey(Integer id) throws SQLException; 15 | public int deleteByPrimaryKey(Integer id) throws SQLException; 16 | public List loadAll() throws SQLException; 17 | public List loadAll(int startRow, int numRows) throws SQLException; 18 | public List loadByWhere(String where) throws SQLException; 19 | public List loadByWhere(String where, Object... fields) throws SQLException; 20 | public List loadByWhere(String where, int startRow, int numRows) throws SQLException; 21 | public T loadUniqueByWhere(String where) throws SQLException; 22 | public T loadUniqueByWhere(String where, Object... fields) throws SQLException; 23 | public int deleteAll() throws SQLException; 24 | public int deleteByWhere(String where) throws SQLException; 25 | public int deleteByWhere(String where, Object... fields) throws SQLException; 26 | public T save(T bean) throws SQLException; 27 | public T insert(T bean) throws SQLException; 28 | public T insert(T bean, boolean orUpdate) throws SQLException; 29 | public T insert(T bean, boolean orUpdate, boolean delayed) throws SQLException; 30 | public T update(T bean) throws SQLException; 31 | public List save(List beans) throws SQLException; 32 | public List insert(List beans) throws SQLException; 33 | public List update(List beans) throws SQLException; 34 | public T loadUniqueUsingTemplate(T bean) throws SQLException; 35 | public List loadUsingTemplate(T bean) throws SQLException; 36 | public List loadUsingTemplate(T bean, int startRow, int numRows) throws SQLException; 37 | public List loadUsingTemplate(T bean, int startRow, int numRows, int searchType) throws SQLException; 38 | public int deleteUsingTemplate(T bean) throws SQLException; 39 | public int countAll() throws SQLException; 40 | public int countWhere(String where) throws SQLException; 41 | public int countWhere(String where, Object... fields) throws SQLException; 42 | public int countUsingTemplate(T bean) throws SQLException; 43 | public int countUsingTemplate(T bean, int startRow, int numRows) throws SQLException; 44 | public int countUsingTemplate(T bean, int startRow, int numRows, int searchType) throws SQLException; 45 | public List decodeResultSet(ResultSet rs, int startRow, int numRows) throws SQLException; 46 | public T decodeRow(ResultSet rs) throws SQLException; 47 | public T metaDataDecodeRow(ResultSet rs) throws SQLException; 48 | public List loadByPreparedStatement(PreparedStatement ps) throws SQLException; 49 | public List loadByPreparedStatement(PreparedStatement ps, int startRow, int numRows) throws SQLException; 50 | } 51 | -------------------------------------------------------------------------------- /sql2java-lib/src/main/java/net/sourceforge/sql2java/lib/Database.java: -------------------------------------------------------------------------------- 1 | package net.sourceforge.sql2java.lib; 2 | 3 | import java.sql.PreparedStatement; 4 | import java.sql.ResultSet; 5 | import java.sql.SQLException; 6 | import java.util.HashMap; 7 | import java.util.List; 8 | import java.util.Map; 9 | import javax.sql.DataSource; 10 | import org.slf4j.Logger; 11 | import org.slf4j.LoggerFactory; 12 | 13 | public abstract class Database { 14 | 15 | private static final Logger log = LoggerFactory.getLogger(Database.class); 16 | 17 | protected Database(DataSource dataSource) { 18 | this.dataSource = dataSource; 19 | this.classMap = new HashMap(); 20 | } 21 | 22 | private final DataSource dataSource; 23 | private final Map classMap; 24 | 25 | protected void registerManager(DaoManager manager) { 26 | Class beanClass = manager.createBean().getClass(); 27 | log.trace("Added mapping for {} : {}", beanClass.getName(), manager.getClass().getName()); 28 | classMap.put(beanClass, manager); 29 | } 30 | 31 | public DaoManager managerForClass(Class type) { 32 | return (DaoManager)getManagerForClass(type); 33 | } 34 | 35 | public DaoManager getManagerForClass(Class type) { 36 | DaoManager daoManager = classMap.get(type); 37 | if (daoManager == null) throw new IllegalArgumentException("No DaoManager found for "+type.getClass().getName()); 38 | return daoManager; 39 | } 40 | 41 | // DAO conveniences 42 | 43 | public T createBean(Class type) { 44 | return (T)getManagerForClass(type).createBean(); 45 | } 46 | 47 | public String getTableName(Class type) { 48 | return getManagerForClass(type).getTableName(); 49 | } 50 | 51 | public T loadByPrimaryKey(Class type, Integer id) throws SQLException { 52 | return (T)getManagerForClass(type).loadByPrimaryKey(id); 53 | } 54 | 55 | public int deleteByPrimaryKey(Class type, Integer id) throws SQLException { 56 | return getManagerForClass(type).deleteByPrimaryKey(id); 57 | } 58 | 59 | public List loadAll(Class type) throws SQLException { 60 | return (List)getManagerForClass(type).loadAll(); 61 | } 62 | 63 | public List loadAll(Class type,int startRow, int numRows) throws SQLException { 64 | return (List)getManagerForClass(type).loadAll(startRow, numRows); 65 | } 66 | 67 | public List loadByWhere(Class type, String where) throws SQLException { 68 | return (List)getManagerForClass(type).loadByWhere(where); 69 | } 70 | 71 | public List loadByWhere(Class type, String where, Object... fields) throws SQLException { 72 | return (List)getManagerForClass(type).loadByWhere(where, fields); 73 | } 74 | 75 | public List loadByWhere(Class type, String where, int startRow, int numRows) throws SQLException { 76 | return (List)getManagerForClass(type).loadByWhere(where, startRow, numRows); 77 | } 78 | 79 | public T loadUniqueByWhere(Class type, String where) throws SQLException { 80 | return (T)getManagerForClass(type).loadUniqueByWhere(where); 81 | } 82 | 83 | public T loadUniqueByWhere(Class type, String where, Object... fields) throws SQLException { 84 | return (T)getManagerForClass(type).loadUniqueByWhere(where, fields); 85 | } 86 | 87 | public int deleteAll(Class type) throws SQLException { 88 | return getManagerForClass(type).deleteAll(); 89 | } 90 | 91 | public int deleteByWhere(Class type, String where) throws SQLException { 92 | return getManagerForClass(type).deleteByWhere(where); 93 | } 94 | 95 | public int deleteByWhere(Class type, String where, Object... fields) throws SQLException { 96 | return getManagerForClass(type).deleteByWhere(where, fields); 97 | } 98 | 99 | public T save(T bean) throws SQLException { 100 | return (T)getManagerForClass(bean.getClass()).save(bean); 101 | } 102 | 103 | public T insert(T bean) throws SQLException { 104 | return (T)getManagerForClass(bean.getClass()).insert(bean); 105 | } 106 | 107 | public T insert(T bean, boolean orUpdate) throws SQLException { 108 | return (T)getManagerForClass(bean.getClass()).insert(bean, orUpdate); 109 | } 110 | 111 | public T insert(T bean, boolean orUpdate, boolean delayed) throws SQLException { 112 | return (T)getManagerForClass(bean.getClass()).insert(bean, orUpdate, delayed); 113 | } 114 | 115 | public T update(T bean) throws SQLException { 116 | return (T)getManagerForClass(bean.getClass()).update(bean); 117 | } 118 | 119 | public List save(List beans) throws SQLException { 120 | if (beans == null || beans.size() < 1) return beans; 121 | Class type = beans.get(0).getClass(); 122 | return (List)getManagerForClass(type).save(beans); 123 | } 124 | 125 | public List insert(List beans) throws SQLException { 126 | if (beans == null || beans.size() < 1) return beans; 127 | Class type = beans.get(0).getClass(); 128 | return (List)getManagerForClass(type).insert(beans); 129 | } 130 | 131 | public List update(List beans) throws SQLException { 132 | if (beans == null || beans.size() < 1) return beans; 133 | Class type = beans.get(0).getClass(); 134 | return (List)getManagerForClass(type).update(beans); 135 | } 136 | 137 | public T loadUniqueUsingTemplate(T bean) throws SQLException { 138 | return (T)getManagerForClass(bean.getClass()).loadUniqueUsingTemplate(bean); 139 | } 140 | 141 | public List loadUsingTemplate(Class type, T bean) throws SQLException { 142 | return (List)getManagerForClass(type).loadUsingTemplate(bean); 143 | } 144 | 145 | public List loadUsingTemplate(T bean, int startRow, int numRows) throws SQLException { 146 | return (List)getManagerForClass(bean.getClass()).loadUsingTemplate(bean, startRow, numRows); 147 | } 148 | 149 | public List loadUsingTemplate(T bean, int startRow, int numRows, int searchType) throws SQLException { 150 | return (List)getManagerForClass(bean.getClass()).loadUsingTemplate(bean, startRow, numRows, searchType); 151 | } 152 | 153 | public boolean delete(T bean) throws SQLException { 154 | if (bean instanceof DaoBean) { 155 | if (((DaoBean)bean).isNew()) return false; 156 | else return (getManagerForClass(bean.getClass()).deleteUsingTemplate(bean) > 0); 157 | } else { 158 | throw new IllegalArgumentException("Not a DaoBean "+bean.getClass().getName()); 159 | } 160 | } 161 | 162 | public int deleteUsingTemplate(T bean) throws SQLException { 163 | return getManagerForClass(bean.getClass()).deleteUsingTemplate(bean); 164 | } 165 | 166 | public int countAll(Class type) throws SQLException { 167 | return getManagerForClass(type).countAll(); 168 | } 169 | 170 | public int countWhere(Class type, String where) throws SQLException { 171 | return getManagerForClass(type).countWhere(where); 172 | } 173 | 174 | public int countWhere(Class type, String where, Object... fields) throws SQLException { 175 | return getManagerForClass(type).countWhere(where, fields); 176 | } 177 | 178 | public int countUsingTemplate(T bean) throws SQLException { 179 | return getManagerForClass(bean.getClass()).countUsingTemplate(bean); 180 | } 181 | 182 | public int countUsingTemplate(T bean, int startRow, int numRows) throws SQLException { 183 | return getManagerForClass(bean.getClass()).countUsingTemplate(bean, startRow, numRows); 184 | } 185 | 186 | public int countUsingTemplate(T bean, int startRow, int numRows, int searchType) throws SQLException { 187 | return getManagerForClass(bean.getClass()).countUsingTemplate(bean, startRow, numRows, searchType); 188 | } 189 | 190 | public List decodeResultSet(Class type, ResultSet rs, int startRow, int numRows) throws SQLException { 191 | return (List)getManagerForClass(type).decodeResultSet(rs, startRow, numRows); 192 | } 193 | 194 | public T decodeRow(Class type, ResultSet rs) throws SQLException { 195 | return (T)getManagerForClass(type).decodeRow(rs); 196 | } 197 | 198 | public T metaDataDecodeRow(Class type, ResultSet rs) throws SQLException { 199 | return (T)getManagerForClass(type).metaDataDecodeRow(rs); 200 | } 201 | 202 | public List loadByPreparedStatement(Class type, PreparedStatement ps) throws SQLException { 203 | return (List)getManagerForClass(type).loadByPreparedStatement(ps); 204 | } 205 | 206 | public List loadByPreparedStatement(Class type, PreparedStatement ps, int startRow, int numRows) throws SQLException { 207 | return (List)getManagerForClass(type).loadByPreparedStatement(ps, startRow, numRows); 208 | } 209 | 210 | // Transactions 211 | 212 | private static final ThreadLocal transaction = 213 | new ThreadLocal() { 214 | @Override protected Txn initialValue() { 215 | return null; 216 | } 217 | }; 218 | 219 | static public Txn beginTransaction() { 220 | if (transaction.get() == null) { 221 | transaction.set(new Txn()); 222 | } else { 223 | throw new IllegalStateException("Transaction already begun."); 224 | } 225 | return transaction.get(); 226 | } 227 | 228 | static public Txn beginTransaction(Txn.Isolation isolation) { 229 | if (transaction.get() == null) { 230 | transaction.set(new Txn(isolation)); 231 | } else { 232 | throw new IllegalStateException("Transaction already begun."); 233 | } 234 | return transaction.get(); 235 | } 236 | 237 | static public Txn currentTransaction() { 238 | return transaction.get(); 239 | } 240 | 241 | static public void commitTransaction() { 242 | if (transaction.get() == null) { 243 | throw new IllegalStateException("No transaction to commit."); 244 | } else { 245 | try { 246 | transaction.get().commit(); 247 | } catch (Exception e) { 248 | throw new RuntimeException(e); 249 | } 250 | } 251 | } 252 | 253 | static public void endTransaction() { 254 | if (transaction.get() == null) { 255 | throw new IllegalStateException("No transaction to commit."); 256 | } else if (transaction.get().isActive()) { 257 | rollbackTransaction(); 258 | } 259 | transaction.remove(); 260 | } 261 | 262 | static public void rollbackTransaction() { 263 | if (transaction.get() == null) { 264 | throw new IllegalStateException("No transaction to rollback."); 265 | } else { 266 | try { 267 | transaction.get().rollback(); 268 | } catch (Exception e) { 269 | throw new RuntimeException(e); 270 | } 271 | } 272 | } 273 | 274 | } 275 | -------------------------------------------------------------------------------- /sql2java-lib/src/main/java/net/sourceforge/sql2java/lib/Txn.java: -------------------------------------------------------------------------------- 1 | package net.sourceforge.sql2java.lib; 2 | 3 | import java.sql.Connection; 4 | import java.sql.SQLException; 5 | import javax.sql.DataSource; 6 | 7 | public class Txn { 8 | 9 | public enum Isolation { 10 | DEFAULT(-1), 11 | READ_COMMITTED(java.sql.Connection.TRANSACTION_READ_COMMITTED), 12 | READ_UNCOMMITTED(java.sql.Connection.TRANSACTION_READ_UNCOMMITTED), 13 | REPEATABLE_READ(java.sql.Connection.TRANSACTION_REPEATABLE_READ), 14 | SERIALIZABLE(java.sql.Connection.TRANSACTION_SERIALIZABLE); 15 | Isolation(int i) { 16 | this.level = i; 17 | } 18 | final int level; 19 | public int getLevel() { return this.level; } 20 | } 21 | 22 | private final Isolation isolation; 23 | private DataSource dataSource; 24 | private boolean active; 25 | private Connection connection; 26 | 27 | public Txn() { 28 | this.isolation = Isolation.DEFAULT; 29 | this.active = false; 30 | } 31 | 32 | public Txn(Isolation isolation) { 33 | this.isolation = isolation; 34 | this.active = false; 35 | } 36 | 37 | public Txn(DataSource dataSource, Isolation isolation) { 38 | this.dataSource = dataSource; 39 | this.isolation = isolation; 40 | this.active = true; 41 | } 42 | 43 | public void setDataSource(DataSource dataSource) { 44 | if (this.dataSource != null) throw new IllegalStateException(); 45 | this.dataSource = dataSource; 46 | this.active = true; 47 | } 48 | 49 | public boolean isDefault() { 50 | return (isolation == Isolation.DEFAULT); 51 | } 52 | 53 | public boolean isActive() { 54 | return active; 55 | } 56 | 57 | public void commit() throws SQLException { 58 | if (connection == null || !active) throw new IllegalStateException(); 59 | try { 60 | connection.commit(); 61 | } finally { 62 | active = false; 63 | connection.close(); 64 | } 65 | } 66 | 67 | public void rollback() throws SQLException { 68 | if (connection == null || !active) throw new IllegalStateException(); 69 | try { 70 | connection.rollback(); 71 | } finally { 72 | active = false; 73 | connection.close(); 74 | } 75 | } 76 | 77 | public Connection getConnection() throws SQLException { 78 | if (dataSource == null || !active) throw new IllegalStateException(); 79 | if (connection != null) return connection; 80 | connection = dataSource.getConnection(); 81 | connection.setAutoCommit(false); 82 | connection.setTransactionIsolation(isolation.getLevel()); 83 | return connection; 84 | } 85 | 86 | } 87 | -------------------------------------------------------------------------------- /sql2java-maven-plugin/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | com.github.xgp 5 | sql2java-maven-plugin 6 | maven-plugin 7 | sql2java-maven-plugin 8 | 9 | 10 | com.github.xgp 11 | sql2java 12 | 0.9.1-SNAPSHOT 13 | 14 | 15 | 16 | 17 | 18 | org.apache.maven.plugins 19 | maven-plugin-plugin 20 | 3.5 21 | 22 | 23 | default-descriptor 24 | 25 | descriptor 26 | 27 | process-classes 28 | 29 | 30 | help-descriptor 31 | 32 | helpmojo 33 | 34 | process-classes 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | org.apache.ant 44 | ant 45 | 1.10.0 46 | 47 | 48 | java2html 49 | j2h 50 | 1.3.1 51 | 52 | 53 | velocity 54 | velocity 55 | 1.4 56 | 57 | 58 | velocity 59 | velocity-dep 60 | 1.4 61 | 62 | 63 | org.hsqldb 64 | sqltool 65 | 66 | 67 | org.hsqldb 68 | hsqldb 69 | runtime 70 | true 71 | 72 | 73 | mysql 74 | mysql-connector-java 75 | 6.0.5 76 | runtime 77 | true 78 | 79 | 80 | org.apache.maven 81 | maven-plugin-api 82 | 3.3.9 83 | 84 | 85 | org.apache.maven.plugin-tools 86 | maven-plugin-annotations 87 | 3.5 88 | provided 89 | 90 | 91 | 92 | 93 | -------------------------------------------------------------------------------- /sql2java-maven-plugin/src/main/java/net/sourceforge/sql2java/CodeWriter.java: -------------------------------------------------------------------------------- 1 | //$Id: CodeWriter.java,v 1.1 2005/10/12 18:44:24 framiere Exp $ 2 | 3 | package net.sourceforge.sql2java; 4 | 5 | //TODO: Add exception handling in this class for the VelocityEngine. 6 | 7 | import java.io.*; 8 | import java.util.*; 9 | import java.sql.Types; 10 | 11 | import org.apache.velocity.Template; 12 | import org.apache.velocity.app.Velocity; 13 | import org.apache.velocity.app.FieldMethodizer; 14 | import org.apache.velocity.VelocityContext; 15 | import org.apache.velocity.exception.*; 16 | import org.apache.velocity.runtime.RuntimeConstants; 17 | import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader; 18 | 19 | 20 | // this class is a mess, would need some brushing, however the generated code is clean and 21 | // that's what really matters 22 | public class CodeWriter 23 | { 24 | static protected Properties props; 25 | 26 | protected static String dateClassName; 27 | protected static String timeClassName; 28 | protected static String timestampClassName; 29 | 30 | protected Database db; 31 | protected Hashtable includeHash, excludeHash; 32 | 33 | protected String basePackage; 34 | protected String destDir; 35 | protected String optimisticLockType; 36 | protected String optimisticLockColumn; 37 | public String classPrefix; 38 | 39 | protected VelocityContext vc; 40 | 41 | public Table table; 42 | protected VelocityContext current_vc; 43 | 44 | protected boolean useLibrary = false; 45 | protected String libraryPackage; 46 | 47 | /////////////////////////////////////////////////////// 48 | // CODE WRITER INIT 49 | /////////////////////////////////////////////////////// 50 | 51 | /** The Default Constructor 52 | * @author Kelvin Nishikawa 53 | * @param props Properties for configuring this instance 54 | */ 55 | public CodeWriter (Database db, Properties props) { 56 | try { 57 | this.db = db; 58 | this.props = props; 59 | 60 | dateClassName = props.getProperty("jdbc2java.date", "java.sql.Date"); 61 | timeClassName = props.getProperty("jdbc2java.time", "java.sql.Time"); 62 | timestampClassName = props.getProperty("jdbc2java.timestamp", "java.sql.Timestamp"); 63 | 64 | // Set properties 65 | basePackage = props.getProperty("mgrwriter.package"); 66 | classPrefix = props.getProperty("mgrwriter.classprefix"); 67 | 68 | excludeHash = setHash(props.getProperty("mgrwriter.exclude")); 69 | if (excludeHash.size() != 0) 70 | System.out.println("Excluding the following tables: " + props.getProperty("mgrwriter.exclude")); 71 | includeHash = setHash(props.getProperty("mgrwriter.include")); 72 | if (includeHash.size() != 0) 73 | System.out.println("Including only the following tables: " + props.getProperty("mgrwriter.include")); 74 | 75 | optimisticLockType = props.getProperty("optimisticlock.type", "none"); 76 | optimisticLockColumn = props.getProperty("optimisticlock.column"); 77 | 78 | if(basePackage == null) throw new Exception("Missing property: mgrwriter.package"); 79 | } catch (Exception e) { 80 | //knishikawa - maybe this needs better exception handling for the Velocity inits 81 | System.err.println("Threw an exception in the CodeWriter constructor:" + e.getMessage()); 82 | e.printStackTrace(); 83 | } 84 | } 85 | 86 | public void setUseLibrary(String libraryPackage) { 87 | this.useLibrary = true; 88 | this.libraryPackage = libraryPackage; 89 | } 90 | 91 | public void setDestinationFolder(String destDir) throws Exception 92 | { 93 | this.destDir = destDir; 94 | if(destDir == null) throw new Exception("Missing property: mgrwriter.destdir"); 95 | 96 | File dir = new File(destDir); 97 | try { 98 | dir.mkdirs(); 99 | } catch (Exception e) { 100 | // ignore 101 | } 102 | 103 | if(!dir.isDirectory() || !dir.canWrite()) throw new Exception("Cannot write to: " + destDir); 104 | } 105 | 106 | 107 | private Hashtable setHash(String str) 108 | { 109 | if (str == null || str.trim().equals("")) { 110 | return new Hashtable(); 111 | } else { 112 | Hashtable hash = new Hashtable(); 113 | StringTokenizer st = new StringTokenizer(str); 114 | while(st.hasMoreTokens()) { 115 | String val = st.nextToken().toLowerCase(); 116 | hash.put(val, val); 117 | } 118 | return hash; 119 | } 120 | } 121 | 122 | public boolean checkTable(Table table) throws Exception 123 | { 124 | System.out.println(" checking table " + table.getName() + " ..."); 125 | boolean error = false; 126 | Column primaryKeys[] = table.getPrimaryKeys(); 127 | if (table.getColumns().length == 0) { 128 | System.err.println(" WARN : no column found !"); 129 | error = false; 130 | } 131 | if (primaryKeys.length == 0) { 132 | System.err.println(" WARN : No primary key is defined on table " + table.getName()); 133 | System.err.println(" Tables without primary key are not fully supported"); 134 | error = false; 135 | } else { 136 | if (primaryKeys.length > 1) { 137 | System.err.print(" WARN : Composite primary key "); 138 | for (int ii = 0; ii < primaryKeys.length; ii++) 139 | System.err.print(primaryKeys[ii].getFullName() + ", "); 140 | System.err.println(); 141 | System.err.println(" Tables with composite primary key are not fully supported"); 142 | } else { 143 | Column pk = primaryKeys[0]; 144 | String pkName = pk.getName(); 145 | String normalKey = table.getName() + "_id"; 146 | if (pkName.equalsIgnoreCase(normalKey) == false) { 147 | System.err.println(" WARN : primary key should of form _ID"); 148 | System.err.println(" found " + pkName + " expected " + normalKey); 149 | } 150 | if (pk.isColumnNumeric() == false) { 151 | System.err.println(" WARN : primary key should be an integer "); 152 | System.err.println(" found " + pk.getJavaType()); 153 | } 154 | } 155 | } 156 | return error; 157 | } 158 | 159 | public void checkDatabase() throws Exception 160 | { 161 | System.out.println("Checking database tables"); 162 | boolean error = false; 163 | Table tables[] = db.getTables(); 164 | for (int i = 0; i < tables.length; i++) { 165 | if (includeHash.size() != 0) { 166 | if (includeHash.get(tables[i].getName().toLowerCase()) != null) { 167 | if (excludeHash.get(tables[i].getName().toLowerCase()) == null) { 168 | boolean b = checkTable(tables[i]); 169 | if (b == true) 170 | error = true; 171 | } 172 | } 173 | } else { 174 | if (excludeHash.size() != 0) { 175 | if (excludeHash.get(tables[i].getName().toLowerCase()) == null) { 176 | boolean b = checkTable(tables[i]); 177 | if (b == true) error = true; 178 | } 179 | } else { 180 | boolean b = checkTable(tables[i]); 181 | if (b == true) error = true; 182 | } 183 | } 184 | } 185 | if (error == true) { 186 | System.err.println(" Failed : at least one of the mandatory rule for sql2java is followed by your schema."); 187 | System.err.println(" Please check the documentation for more information"); 188 | System.exit(-1); 189 | } 190 | System.out.println(" Passed."); 191 | } 192 | 193 | public void cleanup() { 194 | if (db != null) db.cleanup(); 195 | // velocity? 196 | } 197 | 198 | /////////////////////////////////////////////////////// 199 | // CODE WRITER CORE 200 | /////////////////////////////////////////////////////// 201 | 202 | /** The entry point for generating code. */ 203 | public synchronized void process() throws Exception 204 | { 205 | if ("true".equalsIgnoreCase(props.getProperty("check.database"))) 206 | checkDatabase(); 207 | 208 | if ("true".equalsIgnoreCase(props.getProperty("check.only.database"))) 209 | return; 210 | 211 | // Init Velocity 212 | Properties vprops = new Properties(); 213 | vprops.put("runtime.log", "target/velocity.log"); 214 | vprops.put(RuntimeConstants.RESOURCE_LOADER, "classpath"); 215 | vprops.put("classpath.resource.loader.class", ClasspathResourceLoader.class.getName()); 216 | // for file and class 217 | // vprops.put(RuntimeConstants.RESOURCE_LOADER, "file, classpath"); 218 | // vprops.put("file.resource.loader.class", FileResourceLoader.class.getName()); 219 | // vprops.put("file.resource.loader.path", getProperty("mgrwriter.templates.loadingpath",".") ); 220 | // vprops.put("classpath.resource.loader.class", ClasspathResourceLoader.class.getName()); 221 | 222 | Velocity.init(vprops); 223 | vc = new VelocityContext(); 224 | vc.put("CodeWriter", new FieldMethodizer( this )); 225 | vc.put("codewriter", this ); 226 | vc.put("pkg", basePackage); 227 | vc.put("pkgPath", basePackage.replace('.', '/')); 228 | vc.put("useLib", useLibrary); 229 | vc.put("libPath", libraryPackage); 230 | vc.put("strUtil", StringUtilities.getInstance()); 231 | vc.put("db", db); 232 | 233 | current_vc = new VelocityContext(vc); 234 | 235 | System.out.println("Generation in folder " + destDir + " ..."); 236 | String[] schema_templates = getPropertyExploded("mgrwriter.templates.perschema"); 237 | //if (!useLibrary) { 238 | for(int i=0; i 0 */ 425 | public boolean hasRemarks() { 426 | String remarks = table.getRemarks(); 427 | if ( remarks != null ) if ( remarks.length() > 0 ) return true; 428 | return false; 429 | } 430 | 431 | /** Returns the current table's remarks. */ 432 | public String getRemarks() { 433 | return table.getRemarks(); 434 | } 435 | 436 | /** Returns a db.getRelationTable( table ) as a list */ 437 | public List getRelationTable() { 438 | Table [] rtabs = db.getRelationTable(table); 439 | List tables = new ArrayList(rtabs.length); 440 | for ( int i = 0; i < rtabs.length; i++ ) tables.add(rtabs[i]); 441 | return tables; 442 | } 443 | 444 | /** Returns a table's linked tables as a list */ 445 | public List getLinkedTables ( Table rTable ) { 446 | Table[] ltabs = rTable.linkedTables(db, table); 447 | List tables = new ArrayList(ltabs.length); 448 | for ( int i = 0; i < ltabs.length; i++ ) tables.add(ltabs[i]); 449 | return tables; 450 | } 451 | 452 | /** Wrapper for the static Column method */ 453 | public boolean isPresentLock( Collection cols ) { 454 | Column [] columns = new Column[cols.size()]; 455 | int i = 0; 456 | Iterator iter = cols.iterator(); 457 | while ( iter.hasNext() ) columns[i++] = (Column)iter.next(); 458 | return Column.isPresentLock(columns, optimisticLockType, optimisticLockColumn); 459 | } 460 | 461 | /** Find the column in the Collection that matches optimisticLockColumn */ 462 | public Column getLockColumn(Collection cols) { 463 | Iterator iter = cols.iterator(); 464 | while ( iter.hasNext() ) { 465 | Column col = (Column)iter.next(); 466 | if ( col.getName().equalsIgnoreCase( optimisticLockColumn ) ) return col; 467 | } 468 | return null; 469 | } 470 | 471 | /** public accessor for table */ 472 | public Table getTable() { 473 | return table; 474 | } 475 | 476 | /** Check if a list contains an item that is equal() to a string */ 477 | public boolean listContainsString( List list, String string ) { 478 | Object obj = null; 479 | for ( Iterator iter = list.iterator(); 480 | iter.hasNext(); 481 | obj = iter.next() ) { 482 | if ( string.equals(obj) ) return true; 483 | } 484 | return false; 485 | } 486 | 487 | 488 | ////////////////////////////////////////////////////// 489 | // PROPERTY UTILS 490 | ////////////////////////////////////////////////////// 491 | /** Convenience property chop method 492 | * @author Kelvin Nishikawa 493 | * @param key the property to get from this.props 494 | * @return the associated value 495 | */ 496 | static public String getProperty(String key) 497 | { 498 | String s = props.getProperty(key); 499 | return s!=null?s.trim():s; 500 | } 501 | 502 | /** Convenience property chop method 503 | * @author Kelvin Nishikawa 504 | * @param key the property to get from this.props 505 | * @param default_val the default value to return in case not found 506 | * @return the associated value 507 | */ 508 | static public String getProperty(String key, String default_val) { 509 | String s = props.getProperty(key,default_val); 510 | return s!=null?s.trim():s; 511 | } 512 | 513 | 514 | /** 515 | * Return as a String array the key's value. 516 | */ 517 | static public String[] getPropertyExploded(String key) 518 | { 519 | String v = getProperty(key); 520 | if (v==null) { 521 | return new String[0]; 522 | } 523 | ArrayList al = new ArrayList(); 524 | 525 | StringTokenizer st = new StringTokenizer(v, " ,;\t"); 526 | while (st.hasMoreTokens()) { 527 | al.add(st.nextToken().trim()); 528 | } 529 | 530 | return (String[])al.toArray(new String[al.size()]); 531 | } 532 | 533 | } 534 | -------------------------------------------------------------------------------- /sql2java-maven-plugin/src/main/java/net/sourceforge/sql2java/Column.java: -------------------------------------------------------------------------------- 1 | //$Id: Column.java,v 1.4 2005/10/17 09:09:59 framiere Exp $ 2 | 3 | package net.sourceforge.sql2java; 4 | 5 | import java.util.List; 6 | import java.util.Vector; 7 | import java.sql.Types; 8 | 9 | public class Column implements Cloneable { 10 | 11 | // List of possible mapped types. 12 | public static final int M_ARRAY = 0; 13 | public static final int M_BIGDECIMAL = 1; 14 | public static final int M_BOOLEAN = 2; 15 | public static final int M_BYTES = 3; 16 | public static final int M_CLOB = 4; 17 | public static final int M_SQLDATE =5 ; 18 | public static final int M_UTILDATE =6 ; 19 | public static final int M_DOUBLE = 7; 20 | public static final int M_FLOAT = 8; 21 | public static final int M_BLOB = 9; 22 | public static final int M_INTEGER = 10; 23 | public static final int M_LONG = 11; 24 | public static final int M_REF = 12; 25 | public static final int M_STRING =13 ; 26 | public static final int M_TIME = 14; 27 | public static final int M_TIMESTAMP = 15; 28 | public static final int M_URL = 16; 29 | public static final int M_OBJECT = 17; 30 | 31 | private String catalog, schema, tableName, name, remarks, defaultValue; 32 | private int size, decDigits, radix, nullable, ordinal; 33 | private short type; 34 | private boolean isPrimaryKey; 35 | private String strCheckingType = ""; 36 | private Database db; 37 | private List foreignKeys = new Vector(); 38 | private List importedKeys = new Vector(); 39 | 40 | /** 41 | */ 42 | public String toString() 43 | { 44 | return "\n --------- " + tableName + "." + name + " --------- " 45 | + "\n schema = " + schema 46 | + "\n tableName = " + tableName 47 | + "\n catalog = " + catalog 48 | + "\n remarks = " + remarks 49 | + "\n defaultValue = " + defaultValue 50 | + "\n decDigits = " + decDigits 51 | + "\n radix = " + radix 52 | + "\n nullable = " + nullable 53 | + "\n ordinal = " + ordinal 54 | + "\n size = " + size 55 | + "\n type = " + type + " " 56 | + "\n isPrimaryKey = " + (isPrimaryKey ? "true":"false"); 57 | } 58 | 59 | public void setCheckingType(String strValue){this.strCheckingType = strValue;} 60 | public String getCheckingType(){return strCheckingType; } 61 | public void setDatabase(Database db) { this.db = db; } 62 | public void setCatalog(String catalog) { this.catalog = catalog; } 63 | public void setSchema(String schema) { this.schema = schema; } 64 | public void setTableName(String tableName) { this.tableName = tableName; } 65 | public void setName(String name) { this.name = name; } 66 | public void setType(short type) { this.type = type; } 67 | public void setSize(int size) { this.size = size; } 68 | public void setDecimalDigits(int decDigits) { this.decDigits = decDigits; } 69 | public void setRadix(int radix) { this.radix = radix; } 70 | public void setNullable(int nullable) { this.nullable = nullable; } 71 | public void setRemarks(String remarks) { 72 | if (remarks!=null) { 73 | this.remarks = remarks.replaceAll("/\\*", "SLASH*").replaceAll("\\*/", "*SLASH"); 74 | } 75 | } 76 | public void setDefaultValue(String defaultValue) { this.defaultValue = defaultValue; } 77 | public void setOrdinalPosition(int ordinal) { this.ordinal = ordinal; } 78 | public void isPrimaryKey(boolean isPrimaryKey) { this.isPrimaryKey = isPrimaryKey; } 79 | 80 | public String getCatalog() { return catalog; } 81 | public String getSchema() { return schema; } 82 | public String getTableName() { return tableName; } 83 | public String getName() { return name; } 84 | public short getType() { return type; } 85 | public int getSize() { return size; } 86 | public int getDecimalDigits() { return decDigits; } 87 | public int getRadix() { return radix; } 88 | public int getNullable() { return nullable; } 89 | public String getNullableAsString() { return (getNullable() != 0 ? "nullable" : "null not allowed"); } 90 | public String getRemarks() { return remarks==null?"":remarks; } 91 | public String getDefaultValue() { return defaultValue==null?"":defaultValue; } 92 | public int getOrdinalPosition() { return ordinal; } 93 | public boolean isPrimaryKey() { return isPrimaryKey; } 94 | public String getFullName() { return tableName + "." + getName(); } 95 | public String getConstName() { return getName().toUpperCase(); } 96 | 97 | public Object clone() throws CloneNotSupportedException { 98 | return super.clone(); 99 | } 100 | 101 | private void tuoe() { 102 | throw new UnsupportedOperationException("not supported yet: "+ getTableName() + "." + getName() + " " + getJavaTypeAsTypeName()); 103 | } 104 | 105 | private void tiae() { 106 | throw new IllegalArgumentException("No primary type associated: " + getTableName() + "." + getName() ); 107 | } 108 | 109 | /** 110 | * return internal type for the current column 111 | */ 112 | public int getMappedType() { 113 | switch(getType()) { 114 | case Types.ARRAY: return M_ARRAY; 115 | case Types.BIGINT : return M_LONG; 116 | case Types.BINARY : return M_BYTES; 117 | case Types.BIT : return M_BOOLEAN; 118 | case Types.BLOB : return M_BLOB; 119 | case Types.BOOLEAN : return M_BOOLEAN; 120 | case Types.CHAR : return M_STRING; 121 | case Types.CLOB : return M_CLOB; 122 | case Types.DATALINK : return M_URL; 123 | case Types.DATE : 124 | if (CodeWriter.dateClassName.equals("java.util.Date")) return M_UTILDATE; 125 | if (CodeWriter.dateClassName.equals("java.sql.Date")) return M_SQLDATE; 126 | tuoe(); 127 | case Types.DECIMAL : return getDecimalDigits() > 0 ? M_BIGDECIMAL : M_LONG; 128 | case Types.DISTINCT : return M_OBJECT; 129 | case Types.DOUBLE : return M_DOUBLE; 130 | case Types.FLOAT : return M_DOUBLE; 131 | case Types.INTEGER :return M_INTEGER; 132 | case Types.JAVA_OBJECT : return M_OBJECT; 133 | case Types.LONGVARBINARY :return M_BYTES; 134 | case Types.LONGVARCHAR : return M_STRING; 135 | 136 | // case Types.NULL : return M_NULL; 137 | 138 | case Types.NUMERIC : return getDecimalDigits() > 0 ? M_BIGDECIMAL : M_LONG; 139 | case Types.OTHER : return M_OBJECT; 140 | case Types.REAL : return M_FLOAT; 141 | case Types.REF : return M_REF; 142 | case Types.SMALLINT :return M_INTEGER; 143 | case Types.STRUCT : return M_OBJECT; 144 | case Types.TIME : 145 | if (CodeWriter.timeClassName.equals("java.util.Date")) return M_UTILDATE; 146 | if (CodeWriter.timeClassName.equals("java.sql.Time")) return M_TIME; 147 | tuoe(); 148 | case Types.TIMESTAMP : 149 | if (CodeWriter.timestampClassName.equals("java.util.Date")) return M_UTILDATE; 150 | if (CodeWriter.timestampClassName.equals("java.sql.Timestamp")) return M_TIMESTAMP; 151 | tuoe(); 152 | case Types.TINYINT :return M_INTEGER; 153 | case Types.VARBINARY :return M_BYTES; 154 | case Types.VARCHAR :return M_STRING; 155 | default:tuoe(); 156 | } 157 | return -1; 158 | } 159 | 160 | // Convernient helpers: 161 | 162 | /** 163 | * return the java type of the current column 164 | */ 165 | public String getJavaType() 166 | { 167 | switch (getMappedType()) 168 | { 169 | case M_ARRAY: return "Array"; 170 | case M_BIGDECIMAL: return "java.math.BigDecimal"; 171 | case M_BOOLEAN: return "Boolean"; 172 | case M_BYTES: return "byte[]"; 173 | case M_CLOB: return "String"; 174 | case M_SQLDATE: return "java.sql.Date"; 175 | case M_UTILDATE: return "java.util.Date"; 176 | case M_DOUBLE: return "Double"; 177 | case M_FLOAT: return "Float"; 178 | case M_INTEGER: return "Integer"; 179 | case M_LONG: return "Long"; 180 | case M_REF: return "Ref"; 181 | case M_STRING: return "String"; 182 | case M_TIME: return "java.sql.Time"; 183 | case M_TIMESTAMP: return "java.sql.Timestamp"; 184 | case M_URL: return "java.net.URL"; 185 | case M_OBJECT: return "Object"; 186 | } 187 | return null; 188 | } 189 | 190 | /** 191 | * does this column has a primary java type like short, boolean instead of Integer and Boolean ? 192 | */ 193 | public boolean hasPrimaryType() 194 | { 195 | if (getJavaPrimaryType() == null) 196 | return false; 197 | return true; 198 | } 199 | 200 | /** 201 | * return the primary java type of the current column 202 | * return null if no java primary type is available 203 | */ 204 | public String getJavaPrimaryType() throws IllegalArgumentException 205 | { 206 | int decimalDigits = getDecimalDigits(); 207 | int type = getType(); 208 | int size = getSize(); 209 | if ((type == Types.DECIMAL || type == Types.NUMERIC) && decimalDigits == 0) { 210 | if (size == 1) { 211 | return "boolean"; 212 | } 213 | else if (size < 3) { 214 | return "byte"; 215 | } 216 | else if (size < 5) { 217 | return "short"; 218 | } 219 | else if (size < 10) { 220 | return "int"; 221 | } 222 | else if (size < 19) { 223 | return "long"; 224 | } 225 | else { 226 | return "java.math.BigDecimal"; 227 | } 228 | } 229 | switch (getMappedType()) 230 | { 231 | case M_BOOLEAN: return "boolean"; 232 | case M_SQLDATE: return "long"; 233 | case M_UTILDATE: return "long"; 234 | case M_DOUBLE: return "double"; 235 | case M_FLOAT: return "float"; 236 | case M_INTEGER: return "int"; 237 | case M_LONG: return "long"; 238 | case M_TIME: return "long"; 239 | case M_TIMESTAMP: return "long"; 240 | default:break; 241 | } 242 | return null; 243 | } 244 | 245 | /** 246 | * return the string representation of the column type 247 | */ 248 | public String getJavaTypeAsTypeName() 249 | { 250 | switch (getType()) 251 | { 252 | case Types.ARRAY: return "Types.ARRAY"; 253 | case Types.BIGINT : return "Types.BIGINT"; 254 | case Types.BINARY : return "Types.BINARY"; 255 | case Types.BIT : return "Types.BIT"; 256 | case Types.BLOB : return "Types.BLOB"; 257 | case Types.BOOLEAN : return "Types.BOOLEAN"; 258 | case Types.CHAR : return "Types.CHAR"; 259 | case Types.CLOB : return "Types.CLOB"; 260 | case Types.DATALINK : return "Types.DATALINK"; 261 | case Types.DATE : return "Types.DATE"; 262 | case Types.DECIMAL : return "Types.DECIMAL"; 263 | case Types.DISTINCT : return "Types.DISTINCT"; 264 | case Types.DOUBLE : return "Types.DOUBLE"; 265 | case Types.FLOAT : return "Types.FLOAT"; 266 | case Types.INTEGER : return "Types.INTEGER"; 267 | case Types.JAVA_OBJECT : return "Types.JAVA_OBJECT"; 268 | case Types.LONGVARBINARY : return "Types.LONGVARBINARY"; 269 | case Types.LONGVARCHAR : return "Types.LONGVARCHAR"; 270 | case Types.NULL : return "Types.NULL"; 271 | case Types.NUMERIC : return "Types.NUMERIC"; 272 | case Types.OTHER : return "Types.OTHER"; 273 | case Types.REAL : return "Types.REAL"; 274 | case Types.REF : return "Types.REF"; 275 | case Types.SMALLINT : return "Types.SMALLINT"; 276 | case Types.STRUCT : return "Types.STRUCT"; 277 | case Types.TIME : return "Types.TIME"; 278 | case Types.TIMESTAMP : return "Types.TIMESTAMP"; 279 | case Types.TINYINT : return "Types.TINYINT"; 280 | case Types.VARBINARY : return "Types.VARBINARY"; 281 | case Types.VARCHAR : return "Types.VARCHAR"; 282 | default:tuoe(); 283 | } 284 | return null; 285 | } 286 | 287 | /** 288 | * is this column numeric ? 289 | */ 290 | public boolean isColumnNumeric() 291 | { 292 | switch (getMappedType()) 293 | { 294 | case M_DOUBLE: // fall through 295 | case M_FLOAT: // fall through 296 | case M_INTEGER: // fall through 297 | case M_LONG: return true; 298 | default: return false; 299 | } 300 | } 301 | 302 | /** 303 | * is this column a string ? 304 | */ 305 | public boolean isString() 306 | { 307 | if (getMappedType() == M_STRING) 308 | return true; 309 | return false; 310 | } 311 | 312 | /** 313 | * does this type has a compareTo method ? 314 | */ 315 | public boolean hasCompareTo() throws Exception 316 | { 317 | switch(getMappedType()) 318 | { 319 | case M_ARRAY: return false; 320 | case M_BIGDECIMAL: return true; 321 | case M_BOOLEAN: return false; // USE EQUALS INSTEAD 322 | case M_BYTES: return false; 323 | case M_CLOB: return false; 324 | case M_SQLDATE: return true; 325 | case M_UTILDATE: return true; 326 | case M_DOUBLE: return true; 327 | case M_FLOAT: return true; 328 | case M_INTEGER: return true; 329 | case M_LONG: return true; 330 | case M_REF: return false; 331 | case M_STRING: return true; 332 | case M_TIME: return true; 333 | case M_TIMESTAMP: return true; 334 | case M_URL: return false; 335 | case M_OBJECT: return false; 336 | default: return false; 337 | } 338 | } 339 | 340 | /** 341 | * does this type can use equal instead of the compareTo method ? 342 | */ 343 | public boolean useEqualsInSetter() throws Exception 344 | { 345 | switch(getMappedType()) 346 | { 347 | case M_BOOLEAN: return true; 348 | default: return false; 349 | } 350 | } 351 | 352 | /** 353 | * return the resultSet get method for a given position 354 | * the assumption is that the resultset variable is called rs 355 | */ 356 | public String getResultSetMethodObject(String pos) 357 | { 358 | return getResultSetMethodObject("rs", pos); 359 | } 360 | 361 | public String getResultSetMethodObject(String resultSet, String pos) 362 | { 363 | switch (getMappedType()) 364 | { 365 | case M_ARRAY: return resultSet + ".getArray(" + pos + ")"; 366 | case M_LONG : return "getLong(" + resultSet + ", "+pos+")"; 367 | case M_BYTES : return resultSet + ".getBytes(" + pos + ")"; 368 | case M_BLOB : return resultSet + ".getBlob("+pos+")"; 369 | case M_BOOLEAN : return "getBoolean(" + resultSet + ", "+pos+")"; 370 | case M_STRING : return resultSet + ".getString(" + pos + ")"; 371 | //case M_CLOB : return resultSet + ".getClob("+pos+")"; 372 | case M_CLOB : return "getStringFromClob(" + resultSet + ", "+pos+")"; 373 | case M_URL : return resultSet + ".getURL("+pos+")"; 374 | case M_BIGDECIMAL : return resultSet + ".getBigDecimal(" + pos + ")"; 375 | case M_DOUBLE : return "getDouble(" + resultSet + ", "+pos+")"; 376 | case M_FLOAT : return "getFloat(" + resultSet + ", "+pos+")"; 377 | case M_INTEGER : return "getInteger(" + resultSet + ", "+pos+")"; 378 | 379 | case M_OBJECT : return resultSet + ".getObject("+pos+")"; 380 | case M_REF : return resultSet + ".getRef("+pos+")"; 381 | case M_SQLDATE : return resultSet + ".getDate(" + pos + ")"; 382 | case M_TIME :return resultSet + ".getTime(" + pos + ")"; 383 | case M_TIMESTAMP :return resultSet + ".getTimestamp(" + pos + ")"; 384 | case M_UTILDATE : 385 | switch(getType()) { 386 | case Types.TIME: return resultSet + ".getTime(" + pos + ")"; 387 | case Types.TIMESTAMP: return resultSet + ".getTimestamp(" + pos + ")"; 388 | case Types.DATE: return resultSet + ".getDate(" + pos + ")"; 389 | } 390 | default:tuoe(); 391 | } 392 | return null; 393 | } 394 | 395 | 396 | /** 397 | * Maps the SQL type for the column to a "set" method to call on 398 | * the PreparedStatement. 399 | *
400 | * This is used when generating Manager classes. There are some 401 | * variations in how different databases may deal with this, so you 402 | * might look at the OracleManagerWriter to see how you might have 403 | * to override this method for your particular database. 404 | * 405 | * @param var Java code that represents how we'll get access to the 406 | * value to set. You should be able to use this value 407 | * verbatim. Check out the source to this method to 408 | * see what we mean. 409 | * @param pos The position to pass as the first argument of the set 410 | * method. You will be able to use this verbatim too. 411 | * @return The string to write into the generated Manager .java file. 412 | */ 413 | public String getPreparedStatementMethod(String var,int pos) 414 | { 415 | return getPreparedStatementMethod(var, Integer.toString(pos)); 416 | } 417 | 418 | public String getPreparedStatementMethod(String var, String pos) 419 | { 420 | switch(getMappedType()) 421 | { 422 | case M_ARRAY: return "ps.setArray(" + pos + ", " + var + ");"; 423 | case M_LONG: return "setLong(ps, "+pos+", "+var+");"; 424 | case M_BYTES: return "ps.setBytes(" + pos + ", " + var + ");"; 425 | case M_BLOB : return "ps.setBlob(" + pos + ", " + var + ");"; 426 | case M_BOOLEAN : return "setBoolean(ps, "+pos+", "+var+");"; 427 | case M_STRING:return "ps.setString(" + pos + ", " + var + ");"; 428 | //case M_CLOB : return "ps.setClob(" + pos + ", " + var + ");"; 429 | case M_CLOB : return "setClob(ps, " + pos + ", " + var + ");"; 430 | case M_URL : return "ps.setURL(" + pos + ", " + var + ");"; 431 | case M_BIGDECIMAL: return "ps.setBigDecimal(" + pos + ", " + var + ");"; 432 | case M_DOUBLE: return "setDouble(ps, "+pos+", "+var+");"; 433 | case M_INTEGER: return "setInteger(ps, "+pos+", "+var+");"; 434 | case M_OBJECT : return "ps.setObject(" + pos + ", " + var + ");"; 435 | case M_FLOAT: return "setFloat(ps, "+pos+", "+var+");"; 436 | case M_SQLDATE: return "ps.setDate(" + pos + ", " + var + ");"; 437 | case M_TIME: return "ps.setTime(" + pos + ", " + var + ");"; 438 | case M_TIMESTAMP: return "ps.setTimestamp(" + pos + ", " + var + ");"; 439 | case M_UTILDATE: 440 | switch(getType()) { 441 | case Types.TIMESTAMP: return "if (" + var + " == null) ps.setNull("+pos+", "+getJavaTypeAsTypeName()+"); else ps.setTimestamp(" + pos + ", new java.sql.Timestamp(" + var + ".getTime()));"; 442 | case Types.DATE: return "if (" + var + " == null) ps.setNull("+pos+", "+getJavaTypeAsTypeName()+"); else ps.setDate(" + pos + ", new java.sql.Date(" + var + ".getTime()));"; 443 | case Types.TIME: return "if (" + var + " == null) ps.setNull("+pos+", "+getJavaTypeAsTypeName()+"); else ps.setTime(" + pos + ", new java.sql.Time(" + var + ".getTime()));"; 444 | default: return null; 445 | } 446 | case M_REF: return "ps.setRef(" + pos + ", " + var + ");"; 447 | default: return "ps.setObject(" + pos + ", " + var + ");"; 448 | } 449 | } 450 | 451 | /** 452 | * method to convert the given string into the internal java representation 453 | */ 454 | public String getStringConvertionMethod() 455 | { 456 | switch (getMappedType()) 457 | { 458 | case M_BIGDECIMAL: return "new java.math.BigDecimal"; 459 | case M_BOOLEAN: return "new Boolean"; 460 | case M_SQLDATE: return "new java.sql.Date"; 461 | case M_DOUBLE: return "new Double"; 462 | case M_FLOAT: return "new Float"; 463 | case M_INTEGER: return "new Integer"; 464 | case M_LONG: return "new Long"; 465 | case M_STRING: return ""; 466 | case M_TIME: 467 | case M_TIMESTAMP: 468 | case M_UTILDATE: 469 | if (CodeWriter.dateClassName.equals("java.util.GregorianCalendar")) 470 | return "GregorianDate"; 471 | else 472 | return "getDateFromString"; 473 | case M_URL: 474 | case M_OBJECT: 475 | case M_REF: 476 | case M_ARRAY: 477 | case M_BYTES: 478 | case M_CLOB: 479 | default: 480 | System.err.println("type unknown for " + getFullName()); 481 | return ""; 482 | } 483 | } 484 | 485 | /* 486 | * get the default widget name for the current column 487 | */ 488 | public String getDefaultWidget() 489 | { 490 | if (isForeignKey()) 491 | return "SelectWidget"; 492 | if (isString() && (getSize() > 200 || getSize() == -1)) 493 | return "TextAreaWidget"; 494 | 495 | switch (getMappedType()) 496 | { 497 | case M_BOOLEAN: return "BooleanWidget"; 498 | case M_TIME: 499 | case M_TIMESTAMP: 500 | case M_UTILDATE: 501 | case M_SQLDATE: return "DateWidget"; 502 | case M_BIGDECIMAL: 503 | case M_DOUBLE: 504 | case M_FLOAT: 505 | case M_INTEGER: 506 | case M_LONG: 507 | case M_URL: 508 | case M_OBJECT: 509 | case M_REF: 510 | case M_ARRAY: 511 | case M_BYTES: 512 | case M_CLOB: 513 | case M_STRING: return "InputWidget"; 514 | default: 515 | System.err.println("type unknown for " + getFullName()); 516 | return ""; 517 | } 518 | } 519 | 520 | /* 521 | * is there an optimistic locking column ? 522 | */ 523 | static boolean isPresentLock(Column[] cols, String optimisticLockType, String optimisticLockColumn) { 524 | boolean retVal = false; 525 | if (optimisticLockType.equalsIgnoreCase("timestamp")) { 526 | for(int i = 0; i < cols.length; i++) 527 | { 528 | if ( cols[i].getName().equalsIgnoreCase(optimisticLockColumn) && 529 | (cols[i].getMappedType()==Column.M_LONG || cols[i].getMappedType()==Column.M_STRING) ) { 530 | // 531 | retVal = true; 532 | break; 533 | } 534 | } 535 | } 536 | return retVal; 537 | } 538 | 539 | public Table getTable() 540 | { 541 | return db.getTable(getTableName()); 542 | } 543 | 544 | public void addForeignKey(Column col) 545 | { 546 | foreignKeys.add(col); 547 | getTable().addForeignKey(this); 548 | } 549 | 550 | public List getForeignKeys() 551 | { 552 | return foreignKeys; 553 | } 554 | 555 | public void addImportedKey(Column col) 556 | { 557 | importedKeys.add(col); 558 | getTable().addImportedKey(col); 559 | } 560 | 561 | public List getImportedKeys() 562 | { 563 | return importedKeys; 564 | } 565 | 566 | public int countImportedKeys() 567 | { 568 | return importedKeys.size(); 569 | } 570 | 571 | public boolean isImportedKey() 572 | { 573 | if (countImportedKeys() > 0) 574 | return true; 575 | return false; 576 | } 577 | 578 | public Column getForeignColumn() 579 | { 580 | return (Column)foreignKeys.get(0); 581 | } 582 | 583 | public int countForeignKeys() 584 | { 585 | return foreignKeys.size(); 586 | } 587 | 588 | public boolean isForeignKey() 589 | { 590 | if (countForeignKeys() > 0) 591 | return true; 592 | return false; 593 | } 594 | 595 | public String getPropertyTag() 596 | { 597 | return (getTableName() + "." + getName()).toLowerCase(); 598 | } 599 | 600 | public String getVarName() 601 | { 602 | return StringUtilities.convertName(getName(), true); 603 | } 604 | 605 | public String getDefaultRules() 606 | { 607 | String rule = ""; 608 | if (getNullable() == 0 && isPrimaryKey() == false) 609 | rule = rule + " nullnotallowed"; 610 | else 611 | rule = rule + " nullallowed"; 612 | if (getType() == Types.DATE || getType() == Types.TIMESTAMP) 613 | rule = rule + " dateformat"; 614 | return rule; 615 | } 616 | 617 | /** 618 | * is this column described to be in the given type ? 619 | * check in sql2java.properties the table.[TABLENAME].in.[TYPE].exclude & table.[TABLENAME].in.[TYPE].include 620 | */ 621 | public boolean columnFor(String type) 622 | { 623 | String property = "table." + getTableName().toLowerCase() + ".in." + type.toLowerCase(); 624 | String[] exclude = CodeWriter.getPropertyExploded(property + ".exclude"); 625 | String[] include = CodeWriter.getPropertyExploded(property + ".include"); 626 | if (exclude.length == 0 && include.length == 0) 627 | return true; 628 | if (Main.isInArray(include, getName())) 629 | return true; 630 | if (Main.isInArray(exclude, getName())) 631 | return false; 632 | if (include.length == 0) 633 | return true; 634 | return false; 635 | } 636 | 637 | } 638 | -------------------------------------------------------------------------------- /sql2java-maven-plugin/src/main/java/net/sourceforge/sql2java/Database.java: -------------------------------------------------------------------------------- 1 | //$Id: Database.java,v 1.1 2005/10/12 18:44:24 framiere Exp $ 2 | 3 | package net.sourceforge.sql2java; 4 | 5 | import java.sql.*; 6 | import java.util.*; 7 | import java.io.*; 8 | import java.util.Vector; 9 | import java.util.Hashtable; 10 | 11 | public class Database 12 | { 13 | private String tableTypes[]; 14 | private Connection pConnection; 15 | private DatabaseMetaData meta; 16 | private Vector tables; 17 | private Hashtable tableHash; 18 | private String driver, url, username, password, catalog, schema, tablenamepattern; 19 | private boolean retrieveRemarks = true; 20 | 21 | public void setOracleRetrieveRemarks(boolean retrieveRemarks) { this.retrieveRemarks = retrieveRemarks;} 22 | public void setDriver(String driver) { this.driver = driver; } 23 | public void setUrl(String url) { this.url = url; } 24 | public void setUsername(String username) { this.username = username; } 25 | public void setPassword(String password) { this.password = password; } 26 | public void setCatalog(String catalog) { this.catalog = catalog; } 27 | public void setTableNamePattern(String tablenamepattern) { this.tablenamepattern = tablenamepattern; } 28 | public void setTableTypes(String[] tt) { this.tableTypes = tt; } 29 | 30 | public boolean getOracleRetrieveRemarks() { return this.retrieveRemarks; } 31 | public String getDriver() { return driver; } 32 | public String getUrl() { return url; } 33 | public String getUsername() { return username; } 34 | public String getPassword() { return password; } 35 | public String getCatalog() { return catalog; } 36 | public String getSchema() { return schema; } 37 | public String getTableNamePattern() { return tablenamepattern; } 38 | public String[] getTableTypes() { return tableTypes; } 39 | 40 | public void setSchema(String schema) 41 | { 42 | if ("null".equalsIgnoreCase(schema)) 43 | this.schema = null; 44 | else 45 | this.schema = schema; 46 | } 47 | 48 | public void cleanup() { 49 | if (pConnection != null) { 50 | try { 51 | //HACK 52 | if (url.contains("jdbc:hsqldb:file")) { 53 | Statement statement = pConnection.createStatement(); 54 | statement.executeUpdate("SHUTDOWN"); 55 | statement.close(); 56 | } 57 | } catch (SQLException ignore) {} 58 | try { 59 | pConnection.close(); 60 | } catch (SQLException ignore) {} 61 | } 62 | } 63 | 64 | /** 65 | * Return an array of tables having foreign key pointing to the 66 | * passed table. 67 | */ 68 | public Table[] getRelationTable(Table table) 69 | { 70 | Vector vector = new Vector(); 71 | 72 | for (int iIndex = 0; iIndex < tables.size(); iIndex ++) 73 | { 74 | Table tempTable = (Table)tables.get(iIndex); 75 | 76 | // skip itself 77 | if (table.equals(tempTable)) 78 | continue; 79 | 80 | // check only for relation table 81 | if (tempTable.isRelationTable()) 82 | { 83 | if (tempTable.relationConnectsTo(table)) 84 | { 85 | if (!vector.contains(tempTable)) 86 | vector.add(tempTable); 87 | } 88 | } 89 | } 90 | return (Table[])vector.toArray(new Table[0]); 91 | } 92 | 93 | public void load() throws SQLException, ClassNotFoundException 94 | { 95 | // Connect to the database 96 | Class.forName(driver); 97 | 98 | 99 | System.out.println("Connecting to " + username + " on " + url + " ..."); 100 | pConnection = DriverManager.getConnection(url, username, password); 101 | System.out.println(" Connected."); 102 | // if (pConnection instanceof oracle.jdbc.driver.OracleConnection) 103 | // ((oracle.jdbc.driver.OracleConnection)pConnection).setRemarksReporting(getOracleRetrieveRemarks()); 104 | 105 | meta = pConnection.getMetaData(); 106 | System.out.println(" Database server :" + meta.getDatabaseProductName() + "."); 107 | tables = new Vector(); 108 | tableHash = new Hashtable(); 109 | 110 | loadTables(); 111 | loadColumns(); 112 | loadPrimaryKeys(); 113 | 114 | // loadImportedKeys(); 115 | // loadManyToMany(); 116 | // loadIndexes(); // experimental 117 | } 118 | 119 | public Table[] getTables() 120 | { 121 | return (Table[])tables.toArray(new Table[0]); 122 | } 123 | 124 | private void addTable(Table t) { 125 | tables.addElement(t); 126 | tableHash.put(t.getName(), t); 127 | } 128 | 129 | public Table getTable(String name) { 130 | return (Table)tableHash.get(name); 131 | } 132 | 133 | /** 134 | * Load all the tables for this schema. 135 | */ 136 | private void loadTables() throws SQLException 137 | { 138 | System.out.println("Loading table list according to pattern " + tablenamepattern + " ..."); 139 | 140 | // tablenamepattern is now a comma-separated list of patterns 141 | java.util.StringTokenizer st = new java.util.StringTokenizer(tablenamepattern, ",; \t"); 142 | while(st.hasMoreTokens()) { 143 | String pattern = ((String)st.nextToken()).trim(); 144 | ResultSet resultSet = meta.getTables(catalog, schema, pattern, tableTypes); 145 | while(resultSet.next()) 146 | { 147 | Table table = new Table(); 148 | table.setDatabase(this); 149 | table.setCatalog(resultSet.getString("TABLE_CAT")); 150 | 151 | String sch = resultSet.getString("TABLE_SCHEM"); 152 | System.out.println(sch); 153 | // table.setSchema(resultSet.getString("TABLE_SCHEM")); 154 | table.setSchema(sch); 155 | 156 | table.setName(resultSet.getString("TABLE_NAME")); 157 | table.setType(resultSet.getString("TABLE_TYPE")); 158 | table.setRemarks(resultSet.getString("REMARKS")); 159 | addTable(table); 160 | System.out.println(" table " + table.getName() + " found"); 161 | } 162 | resultSet.close(); 163 | } 164 | } 165 | 166 | /** 167 | * For each table, load all the columns. 168 | */ 169 | private void loadColumns() throws SQLException 170 | { 171 | Table tables[] = getTables(); 172 | 173 | System.out.println("Loading columns ..."); 174 | boolean b = false; 175 | for(int i = 0; i < tables.length; i++) 176 | { 177 | Table table = tables[i]; 178 | ResultSet resultSet = meta.getColumns(catalog, schema, table.getName(), "%"); 179 | Column c = null; 180 | 181 | while(resultSet.next()) 182 | { 183 | c = new Column(); 184 | c.setDatabase(this); 185 | c.setCatalog(resultSet.getString("TABLE_CAT")); 186 | c.setSchema(resultSet.getString("TABLE_SCHEM")); 187 | c.setTableName(resultSet.getString("TABLE_NAME")); 188 | c.setName(resultSet.getString("COLUMN_NAME")); 189 | c.setType(resultSet.getShort("DATA_TYPE")); 190 | c.setSize(resultSet.getInt("COLUMN_SIZE")); 191 | c.setDecimalDigits(resultSet.getInt("DECIMAL_DIGITS")); 192 | c.setRadix(resultSet.getInt("NUM_PREC_RADIX")); 193 | c.setNullable(resultSet.getInt("NULLABLE")); 194 | c.setRemarks(resultSet.getString("REMARKS")); 195 | c.setDefaultValue(resultSet.getString("COLUMN_DEF")); 196 | c.setOrdinalPosition(resultSet.getInt("ORDINAL_POSITION")); 197 | table.addColumn(c); 198 | } 199 | System.out.println(" " + table.getName() + " found " + table.countColumns() + " columns"); 200 | 201 | resultSet.close(); 202 | } 203 | } 204 | 205 | /** 206 | * For each table, load the primary keys. 207 | */ 208 | private void loadPrimaryKeys() throws SQLException 209 | { 210 | System.out.println("Loading primary keys ..."); 211 | Table tables[] = getTables(); 212 | 213 | for(int i = 0; i < tables.length; i++) 214 | { 215 | Table table = tables[i]; 216 | ResultSet resultSet = meta.getPrimaryKeys(catalog, schema, table.getName()); 217 | 218 | while(resultSet.next()) 219 | { 220 | Column col = table.getColumn(resultSet.getString("COLUMN_NAME")); 221 | table.addPrimaryKey(col); 222 | System.out.println(" " + col.getFullName() + " found"); 223 | } 224 | 225 | resultSet.close(); 226 | } 227 | } 228 | 229 | /** 230 | * For each table, load the imported key. 231 | *
232 | * An imported key is the other's table column clone. Its 233 | * ForeignKeyColName corresponds to the table's column name that 234 | * points to the other's table. 235 | */ 236 | private void loadImportedKeys() throws SQLException 237 | { 238 | System.out.println("Loading imported keys ..."); 239 | Table tables[] = getTables(); 240 | 241 | for(int i = 0; i < tables.length; i++) 242 | { 243 | Table table = tables[i]; 244 | ResultSet resultSet = meta.getImportedKeys(catalog, schema, table.getName()); 245 | while(resultSet.next()) 246 | { 247 | String tabName = resultSet.getString("FKTABLE_NAME"); 248 | String colName = resultSet.getString("FKCOLUMN_NAME"); 249 | 250 | String foreignTabName= resultSet.getString("PKTABLE_NAME"); 251 | String foreignColName= resultSet.getString("PKCOLUMN_NAME"); 252 | 253 | Column col = getTable(tabName).getColumn(colName); 254 | Column foreignCol = getTable(foreignTabName).getColumn(foreignColName); 255 | 256 | col.addForeignKey(foreignCol); 257 | foreignCol.addImportedKey(col); 258 | //getTable(foreignTabName).addImportedKey(col); 259 | 260 | System.out.println(" " + col.getFullName() + " -> " + foreignCol.getFullName() + " found "); 261 | } 262 | 263 | resultSet.close(); 264 | } 265 | } 266 | 267 | // 268 | // could avoid db call. 269 | // In each current table an entry is: 270 | // other table column (that points to current table) | current pk column 271 | // [other table has nb col. == pk length] 272 | private void loadManyToMany() throws SQLException 273 | { 274 | System.out.println("Loading many to many relationships..."); 275 | Table tables[] = getTables(); 276 | 277 | for(int i = 0; i < tables.length; i++) 278 | { 279 | Table table = tables[i]; 280 | 281 | // if(table.getColumns().length == table.getPrimaryKeys().length) 282 | { 283 | ResultSet resultSet = meta.getImportedKeys(catalog, schema, table.getName()); 284 | 285 | while(resultSet.next()) 286 | { 287 | String tabName = resultSet.getString("PKTABLE_NAME"); 288 | String colName = resultSet.getString("PKCOLUMN_NAME"); 289 | System.out.println(" many to many " + tabName + " " + colName); 290 | 291 | Table pkTable = getTable(tabName); 292 | Column fkCol = table.getColumn(resultSet.getString("FKCOLUMN_NAME")); 293 | 294 | if(pkTable != null) 295 | { 296 | Column pkCol = pkTable.getColumn(colName); 297 | 298 | if(pkCol != null && fkCol != null) 299 | { 300 | pkTable.addManyToManyKey(fkCol, pkCol); 301 | } 302 | } 303 | } 304 | 305 | resultSet.close(); 306 | } 307 | } 308 | } 309 | 310 | /** 311 | * For each table, load the indexes. 312 | */ 313 | private void loadIndexes() throws SQLException 314 | { 315 | System.out.println("Loading indexes ..."); 316 | Table tables[] = getTables(); 317 | 318 | for(int i = 0; i < tables.length; i++) 319 | { 320 | Table table = tables[i]; 321 | ResultSet resultSet = meta.getIndexInfo(catalog, 322 | schema, 323 | table.getName(), 324 | true, 325 | true); 326 | while(resultSet.next()) 327 | { 328 | String colName = resultSet.getString("COLUMN_NAME"); 329 | String indName = resultSet.getString("INDEX_NAME"); 330 | 331 | if (colName != null && indName != null) { 332 | Column col = table.getColumn(colName); 333 | if (!col.isPrimaryKey()) 334 | System.out.println(" Found interesting index " + indName + " on " + 335 | colName + " for table " + table.getName()); 336 | } 337 | } 338 | 339 | resultSet.close(); 340 | } 341 | } 342 | 343 | public String[] getAllPackages() 344 | { 345 | Vector vector = new Vector(); 346 | for (int iIndex = 0; iIndex < tables.size(); iIndex ++) 347 | { 348 | Table table = (Table)tables.get(iIndex); 349 | String packages[] = table.getLinkedPackages(); 350 | for (int i = 0; i < packages.length; i++) 351 | { 352 | if (vector.contains(packages[i]) == false) 353 | { 354 | vector.add(packages[i]); 355 | } 356 | } 357 | } 358 | return (String[])vector.toArray(new String[0]); 359 | } 360 | 361 | } 362 | -------------------------------------------------------------------------------- /sql2java-maven-plugin/src/main/java/net/sourceforge/sql2java/Main.java: -------------------------------------------------------------------------------- 1 | //$Id: Main.java,v 1.1 2005/10/12 18:44:24 framiere Exp $ 2 | 3 | package net.sourceforge.sql2java; 4 | 5 | import java.util.*; 6 | import java.io.*; 7 | import java.sql.SQLException; 8 | 9 | public class Main { 10 | 11 | /** 12 | * properties given in the command line 13 | */ 14 | private static Properties prop; 15 | 16 | /** 17 | * main entry point 18 | */ 19 | public static void main(String argv[]) 20 | { 21 | main(argv, null); 22 | } 23 | 24 | /** 25 | * main entry point 26 | */ 27 | public static void main(String argv[], Map overideFileProperties) 28 | { 29 | // Check for required argument 30 | if(argv == null || argv.length < 1) { 31 | System.err.println("Usage: java net.sourceforge.sql2java.Main "); 32 | System.exit(1); 33 | } 34 | 35 | //properties already here ? 36 | prop = new Properties(); 37 | try 38 | { 39 | prop.load(new FileInputStream(argv[0])); 40 | Database db = new Database(); 41 | db.setDriver(getProperty("jdbc.driver")); 42 | db.setUrl(getProperty("jdbc.url")); 43 | db.setUsername(getProperty("jdbc.username")); 44 | db.setPassword(getProperty("jdbc.password")); 45 | db.setCatalog(getProperty("jdbc.catalog")); 46 | db.setSchema(getProperty("jdbc.schema")); 47 | db.setTableNamePattern(getProperty("jdbc.tablenamepattern")); 48 | 49 | if (overideFileProperties != null) 50 | prop.putAll(overideFileProperties); 51 | 52 | if ("false".equalsIgnoreCase(getProperty("jdbc.oracle.retrieve.remarks"))) 53 | db.setOracleRetrieveRemarks(false); 54 | else 55 | db.setOracleRetrieveRemarks(true); 56 | 57 | String tt = getProperty("jdbc.tabletypes", "TABLE"); 58 | StringTokenizer st = new StringTokenizer(tt, ",; \t"); 59 | ArrayList al = new ArrayList(); 60 | 61 | while(st.hasMoreTokens()) { 62 | al.add(((String)st.nextToken()).trim()); 63 | } 64 | 65 | db.setTableTypes((String[])al.toArray(new String[al.size()])); 66 | 67 | db.load(); 68 | 69 | CodeWriter writer = new CodeWriter(db, prop); 70 | // override destdir if given 71 | if (argv.length > 1) 72 | writer.setDestinationFolder(argv[1]); 73 | writer.process(); 74 | } 75 | catch(Exception e) 76 | { 77 | e.printStackTrace(); 78 | System.exit(1); 79 | } 80 | } 81 | 82 | public static String getProperty(String key) 83 | { 84 | String s = prop.getProperty(key); 85 | return s!=null?s.trim():s; 86 | } 87 | 88 | /** 89 | * helper method with default values 90 | */ 91 | public static String getProperty(String key, String default_val) 92 | { 93 | String s = getProperty(key); 94 | if (s == null) 95 | return default_val; 96 | return s; 97 | } 98 | 99 | /** 100 | * is the given code in the string array ? 101 | */ 102 | public static boolean isInArray(String[] ar, String code) 103 | { 104 | if (ar == null) 105 | return false; 106 | for (int i = 0; i < ar.length; i ++) 107 | { 108 | if (code.equalsIgnoreCase(ar[i])) 109 | return true; 110 | } 111 | return false; 112 | } 113 | 114 | } 115 | -------------------------------------------------------------------------------- /sql2java-maven-plugin/src/main/java/net/sourceforge/sql2java/StringUtilities.java: -------------------------------------------------------------------------------- 1 | //$Id: StringUtilities.java,v 1.3 2005/10/17 22:04:10 framiere Exp $ 2 | 3 | package net.sourceforge.sql2java; 4 | 5 | import java.io.*; 6 | 7 | /** 8 | * @author Kelvin Nishikawa 9 | * 10 | * This utility class handles various SQL -> Java String conversions for code in various templates. 11 | * Use sharedInstance() to get the singleton instance. 12 | * 13 | * Most of these methods were excised to here from the CodeWriter class for good housekeeping. 14 | * 15 | */ 16 | public final class StringUtilities { 17 | 18 | static private StringUtilities singleton = new StringUtilities(); 19 | 20 | // TODO: convert into velocity macros 21 | static public final String PREFIX = ""; 22 | static public final String BASE_SUFFIX = ""; 23 | static public final String MANAGER_SUFFIX = "Manager"; 24 | static public final String BEAN_SUFFIX = ""; 25 | static public final String RELATIONNAL_BEAN_SUFFIX = "Relationnal_Bean"; 26 | static public final String ITERATOR_SUFFIX = "Iterator"; 27 | static public final String FACTORY_SUFFIX = "Factory"; 28 | static public final String EXCEPTION_SUFFIX = "Exception"; 29 | 30 | private StringUtilities () { } 31 | 32 | /** This is the default method for obtaining a StringUtilities instance. 33 | * @return The shared instance 34 | */ 35 | static public synchronized StringUtilities getInstance() { 36 | return singleton; 37 | } 38 | 39 | public String getPackageAsPath(String pkg){ 40 | if (pkg == null) 41 | return ""; 42 | return pkg.replace('.', '/'); 43 | } 44 | 45 | public String getDefaultRules(Column col){ 46 | return col.getDefaultRules(); 47 | } 48 | 49 | public String getPropertyTag(Column col){ 50 | return col.getPropertyTag(); 51 | } 52 | 53 | // TODO: convert into velocity macros 54 | public String convertClass(String table, String type) 55 | { 56 | String suffix = ""; 57 | String postfix = ""; 58 | if ("".equalsIgnoreCase(PREFIX) == false) 59 | suffix = suffix + "_"; 60 | if ("".equalsIgnoreCase(type) == false) 61 | postfix = "_" + type; 62 | return convertName(suffix + table + postfix); 63 | } 64 | 65 | public String getCoreClass(Table table) 66 | { 67 | return convertClass(table.getName(), BASE_SUFFIX); 68 | } 69 | 70 | public String getCoreClass(String table) 71 | { 72 | return convertClass(table, BASE_SUFFIX); 73 | } 74 | 75 | public String getBeanClass(Table table) 76 | { 77 | return convertClass(table.getName(), BEAN_SUFFIX); 78 | } 79 | 80 | public String getBeanClass(String table) 81 | { 82 | return convertClass(table, BEAN_SUFFIX); 83 | } 84 | 85 | public String getRelationnalBeanClass(Table table) 86 | { 87 | return convertClass(table.getName(), RELATIONNAL_BEAN_SUFFIX); 88 | } 89 | 90 | public String getRelationnalBeanClass(String table) 91 | { 92 | return convertClass(table, RELATIONNAL_BEAN_SUFFIX); 93 | } 94 | 95 | public String getFactoryClass(Table table) 96 | { 97 | return convertClass(table.getName(), FACTORY_SUFFIX); 98 | } 99 | 100 | public String getFactoryClass(String table) 101 | { 102 | return convertClass(table, FACTORY_SUFFIX); 103 | } 104 | 105 | public String getExceptionClass(Table table) 106 | { 107 | return convertClass(table.getName(), EXCEPTION_SUFFIX); 108 | } 109 | 110 | public String getExceptionClass(String table) 111 | { 112 | return convertClass(table, EXCEPTION_SUFFIX); 113 | } 114 | 115 | public String getIteratorClass(Table table) 116 | { 117 | return convertClass(table.getName(), ITERATOR_SUFFIX); 118 | } 119 | 120 | public String getIteratorClass(String table) 121 | { 122 | return convertClass(table, ITERATOR_SUFFIX); 123 | } 124 | 125 | public String getManagerClass(Table table) 126 | { 127 | return convertClass(table.getName(), MANAGER_SUFFIX); 128 | } 129 | 130 | public String getManagerClass(String table) 131 | { 132 | return convertClass(table, MANAGER_SUFFIX); 133 | } 134 | 135 | public String getManagerObjectName(Table table) 136 | { 137 | return getManagerObjectName(table.getName()); 138 | } 139 | 140 | public String getManagerObjectName(String table) 141 | { 142 | String objName = convertClass(table, MANAGER_SUFFIX); 143 | char f = Character.toLowerCase(objName.charAt(0)); 144 | return Character.toString(f)+objName.substring(1); 145 | } 146 | 147 | public String getStringConvertionMethod(Column col){ 148 | return col.getStringConvertionMethod(); 149 | } 150 | 151 | public String getGetMethod(Column col) { 152 | return getGetMethod(col.getName()); 153 | } 154 | 155 | public String getSetMethod(Column col) { 156 | return getSetMethod(col.getName()); 157 | } 158 | 159 | public String getModifiedMethod(Column col) { 160 | return getModifiedMethod(col.getName()); 161 | } 162 | 163 | public String getInitializedMethod(Column col) { 164 | return getInitializedMethod(col.getName()); 165 | } 166 | 167 | public String getWidgetMethod(Column col) { 168 | return getWidgetMethod(col.getName()); 169 | } 170 | 171 | 172 | public String getGetMethod(String col) { 173 | return convertName("get_" + escape(col), true); 174 | } 175 | 176 | public String getSetMethod(String col) { 177 | return convertName("set_" + escape(col), true); 178 | } 179 | 180 | public String getModifiedMethod(String col) { 181 | return convertName("is_" + escape(col) + "_modified", true); 182 | } 183 | 184 | public String getInitializedMethod(String col) { 185 | return convertName("is_" + escape(col) + "_initialized", true); 186 | } 187 | 188 | public String getWidgetMethod(String col) { 189 | return convertName("get_" + escape(col) + "_widget", true); 190 | } 191 | 192 | public String getVarName(Column c) { 193 | return convertName(escape(c), true); 194 | } 195 | 196 | public String getVarName(String c) { 197 | return convertName(escape(c), true); 198 | } 199 | 200 | public String getModifiedVarName(Column c) { 201 | return getVarName(c) + "_is_modified"; // already escaped 202 | } 203 | 204 | public String getInitializedVarName(Column c) { 205 | return getVarName(c) + "_is_initialized";// already escaped 206 | } 207 | 208 | // foreign keys 209 | public String getForeignKeyVarName(Column c) { 210 | return convertName(escape(c) + "_object", true); 211 | } 212 | 213 | public String getForeignKeyModifiedVarName(Column c) { 214 | return getVarName(c) + "_object_is_modified"; // already escaped 215 | } 216 | 217 | public String getForeignKeyInitializedVarName(Column c) { 218 | return getVarName(c) + "_object_is_initialized";// already escaped 219 | } 220 | 221 | public String getForeignKeyInitializedMethod(Column col) { 222 | return convertName("is_" + escape(col) + "_object_initialized", true); 223 | } 224 | 225 | public String getForeignKeyGetMethod(Column col) { 226 | return convertName("get_" + escape(col) + "_object", true); 227 | } 228 | 229 | public String getForeignKeySetMethod(Column col) { 230 | return convertName("set_" + escape(col) + "_object", true); 231 | } 232 | 233 | public String getForeignKeyModifiedMethod(Column col) { 234 | return convertName("is_" + escape(col) + "_object_modified", true); 235 | } 236 | 237 | public String getForeignKeyVarName(String col) { 238 | return convertName(escape(col) + "_object", true); 239 | } 240 | 241 | public String getForeignKeyModifiedVarName(String c) { 242 | return getVarName(c) + "_object_is_modified"; // already escaped 243 | } 244 | 245 | public String getForeignKeyInitializedVarName(String c) { 246 | return getVarName(c) + "_object_is_initialized";// already escaped 247 | } 248 | 249 | public String getForeignKeyInitializedMethod(String col) { 250 | return convertName("is_" + escape(col) + "_object_initialized", true); 251 | } 252 | 253 | public String getForeignKeyGetMethod(String col) { 254 | return convertName("get_" + escape(col) + "_object", true); 255 | } 256 | 257 | public String getForeignKeySetMethod(String col) { 258 | return convertName("set_" + escape(col) + "_object", true); 259 | } 260 | 261 | public String getForeignKeyModifiedMethod(String col) { 262 | return convertName("is_" + escape(col) + "_object_modified", true); 263 | } 264 | 265 | // imported keys 266 | public String getImportedKeyVarName(Column c) { 267 | return convertName(escape(c) + "_collection", true); 268 | } 269 | 270 | public String getImportedKeyModifiedVarName(Column c) { 271 | return getVarName(c) + "_collection_is_modified"; // already escaped 272 | } 273 | 274 | public String getImportedKeyInitializedVarName(Column c) { 275 | return getVarName(c) + "_collection_is_initialized";// already escaped 276 | } 277 | 278 | public String getImportedKeyInitializedMethod(Column col) { 279 | return convertName("is_" + escape(col) + "_collection_initialized", true); 280 | } 281 | 282 | public String getImportedKeyGetMethod(Column col) { 283 | return convertName("get_" + escape(col) + "_collection", true); 284 | } 285 | 286 | public String getImportedKeyAddMethod(Column col) { 287 | return convertName("add_" + escape(col) + "", true); 288 | } 289 | 290 | public String getImportedKeySetMethod(Column col) { 291 | return convertName("set_" + escape(col) + "_collection", true); 292 | } 293 | 294 | public String getImportedKeyModifiedMethod(Column col) { 295 | return convertName("is_" + escape(col) + "_collection_modified", true); 296 | } 297 | 298 | public String getImportedKeyVarName(String col) { 299 | return convertName(escape(col) + "_collection", true); 300 | } 301 | 302 | public String getImportedKeyModifiedVarName(String c) { 303 | return getVarName(c) + "_collection_is_modified"; // already escaped 304 | } 305 | 306 | public String getImportedKeyInitializedVarName(String c) { 307 | return getVarName(c) + "_collection_is_initialized";// already escaped 308 | } 309 | 310 | public String getImportedKeyInitializedMethod(String col) { 311 | return convertName("is_" + escape(col) + "_collection_initialized", true); 312 | } 313 | 314 | public String getImportedKeyGetMethod(String col) { 315 | return convertName("get_" + escape(col) + "_collection", true); 316 | } 317 | 318 | public String getImportedKeyAddMethod(String col) { 319 | return convertName("add_" + escape(col) + "", true); 320 | } 321 | 322 | public String getImportedKeySetMethod(String col) { 323 | return convertName("set_" + escape(col) + "_collection", true); 324 | } 325 | 326 | public String getImportedKeyModifiedMethod(String col) { 327 | return convertName("is_" + escape(col) + "_collection_modified", true); 328 | } 329 | 330 | 331 | public String getJavaPrimaryType( Column c ) { 332 | try { 333 | return c.getJavaPrimaryType(); 334 | } catch ( Exception e ) { 335 | return null; 336 | } 337 | } 338 | 339 | public String convertName(String name) { 340 | return convertName(name, false); 341 | } 342 | 343 | public String convertName(Column col) { 344 | return convertName(col.getName(), false); 345 | } 346 | 347 | public String convertName(Table table) { 348 | return convertName(table.getName(), false); 349 | } 350 | 351 | /** 352 | * Converts name into a more Java-ish style name. 353 | * @author netkernel 354 | *
355 | * Basically it looks for underscores, removes them, and makes the 356 | * letter after the underscore a capital letter. If wimpyCaps is true, 357 | * then the first letter of the name will be lowercase, otherwise it 358 | * will be uppercase. Here are some examples: 359 | *

360 | * member_profile becomes MemberProfile 361 | *
362 | * firstname           becomes  Firstname 363 | */ 364 | public static String convertName(String name, boolean wimpyCaps) { 365 | StringBuffer buffer = new StringBuffer(name.length()); 366 | char list[] = name.toLowerCase().toCharArray(); 367 | //char list[] = name.toCharArray(); 368 | for(int i = 0; i < list.length; i++) { 369 | if(i == 0 && !wimpyCaps) { 370 | buffer.append(Character.toUpperCase(list[i])); 371 | } else if(list[i] == '_' && (i+1) < list.length && i != 0) { 372 | buffer.append(Character.toUpperCase(list[++i])); 373 | } else buffer.append(list[i]); 374 | } 375 | return buffer.toString(); 376 | } 377 | // ORIGINAL CONVERT STRING 378 | // public static String convertName(String name, boolean wimpyCaps) { 379 | // StringBuffer buffer = new StringBuffer(name.length()); 380 | // char list[] = name.toLowerCase().toCharArray(); 381 | // for(int i = 0; i < list.length; i++) { 382 | // if(i == 0 && !wimpyCaps) { 383 | // buffer.append(Character.toUpperCase(list[i])); 384 | // } else if(list[i] == '_' && (i+1) < list.length && i != 0) { 385 | // buffer.append(Character.toUpperCase(list[++i])); 386 | // } else buffer.append(list[i]); 387 | // } 388 | // return buffer.toString(); 389 | // } 390 | 391 | private String escape(String s) { 392 | return isReserved(s) ? ("my_"+s) : s; 393 | } 394 | 395 | private String escape(Column s) { 396 | return isReserved(s.getName()) ? ("my_"+s.getName()) : s.getName(); 397 | } 398 | 399 | boolean isReserved(String s) { 400 | for(int i=0; i 1; 23 | } 24 | 25 | /** 26 | * Tells whether if one of this table's columns (imported key) 27 | * points to one of the otherTable's pk. 28 | */ 29 | public boolean relationConnectsTo(Table otherTable) 30 | { 31 | if (this.equals(otherTable)) 32 | { 33 | return false; 34 | } 35 | 36 | for (int i = 0; i < foreignKeys.size(); i++) 37 | { 38 | Column c = (Column) importedKeys.get(i); 39 | if (c.getTableName().equals(otherTable.getName())) 40 | { 41 | return true; 42 | } 43 | } 44 | return false; 45 | } 46 | 47 | /** 48 | * Return, beside the passed table, the tables this table points to. 49 | */ 50 | public Table[] linkedTables(Database pDatabase, Table pTable) 51 | { 52 | Vector vector = new Vector(); 53 | 54 | for (int iIndex = 0; iIndex < importedKeys.size(); iIndex++) 55 | { 56 | Column pColumn = (Column) importedKeys.get(iIndex); 57 | if (pColumn.getTableName().equals(pTable.getName()) == false) 58 | { 59 | Table pTableToAdd = pDatabase.getTable(pColumn.getTableName()); 60 | if (vector.contains(pTableToAdd) == false) 61 | vector.add(pTableToAdd); 62 | } 63 | } 64 | return (Table[])vector.toArray(new Table[0]); 65 | } 66 | 67 | /** 68 | * Return the imported key pointing to the passed table. 69 | */ 70 | public Column getForeignKeyFor(Table pTable) 71 | { 72 | Vector vector = new Vector(); 73 | for (int iIndex = 0; iIndex < importedKeys.size(); iIndex++) 74 | { 75 | Column pColumn = (Column) importedKeys.get(iIndex); 76 | if (pColumn.getTableName().equals(pTable.getName())) 77 | return pColumn; 78 | } 79 | return null; 80 | } 81 | 82 | public void setDatabase(Database db) 83 | { 84 | this.db = db; 85 | } 86 | public void setCatalog(String catalog) 87 | { 88 | this.catalog = catalog; 89 | } 90 | public void setSchema(String schema) 91 | { 92 | this.schema = schema; 93 | } 94 | public void setName(String name) 95 | { 96 | this.name = name; 97 | } 98 | public void setType(String type) 99 | { 100 | this.type = type; 101 | } 102 | public void setRemarks(String remarks) 103 | { 104 | if (remarks!=null) { 105 | this.remarks = remarks.replaceAll("/\\*", "SLASH*").replaceAll("\\*/", "*SLASH"); 106 | } 107 | // else setRemarks("No remarks in this table /* escape me */ /** me too ****/ / * not me * /"); 108 | } 109 | 110 | public String getCatalog() 111 | { 112 | return catalog; 113 | } 114 | public String getSchema() 115 | { 116 | return schema; 117 | } 118 | public String getName() 119 | { 120 | return name; 121 | } 122 | public String getType() 123 | { 124 | return type; 125 | } 126 | public String getRemarks() 127 | { 128 | return remarks==null?"":remarks; 129 | } 130 | 131 | public Column[] getColumns() 132 | { 133 | return (Column[])cols.toArray(new Column[0]); 134 | } 135 | 136 | public Column getColumn(String name) 137 | { 138 | return (Column) colHash.get(name.toLowerCase()); 139 | } 140 | 141 | public void addColumn(Column column) 142 | { 143 | colHash.put(column.getName().toLowerCase(), column); 144 | cols.addElement(column); 145 | } 146 | 147 | public void removeColumn(Column column) 148 | { 149 | cols.removeElement(column); 150 | colHash.remove(column.getName().toLowerCase()); 151 | } 152 | 153 | public Column[] getPrimaryKeys() 154 | { 155 | return (Column[])priKey.toArray(new Column[0]); 156 | } 157 | 158 | public void addPrimaryKey(Column column) 159 | { 160 | priKey.addElement(column); 161 | column.isPrimaryKey(true); 162 | } 163 | 164 | public Column[] getImportedKeys() 165 | { 166 | return (Column[])importedKeys.toArray(new Column[0]); 167 | } 168 | 169 | public void addImportedKey(Column column) 170 | { 171 | if (importedKeys.contains(column) == false) 172 | importedKeys.addElement(column); 173 | } 174 | 175 | /** 176 | * Returns a 2-D array of the keys in this table that form a many 177 | * to many relationship. 178 | *
179 | * The size of the first dimension is based on the number of 180 | * unique tables that are being managed. The second dimension 181 | * is always 2 elements. The first element is the column in the 182 | * relationship table itself. The second column is the primary 183 | * key column in the target table. 184 | */ 185 | public Column[][] getManyToManyKeys() 186 | { 187 | 188 | // // it matters only if we have 2 entries. 189 | // if (manyToManyHash.size()<=1) { 190 | // return new Column[0][0]; 191 | // } 192 | 193 | Column list[][] = new Column[manyToManyHash.size()][2]; 194 | int i = 0; 195 | for (Enumeration e = manyToManyHash.keys(); e.hasMoreElements(); i++) 196 | { 197 | Column fk = (Column) e.nextElement(); 198 | Column pk = (Column) manyToManyHash.get(fk); 199 | list[i][0] = fk; 200 | list[i][1] = pk; 201 | } 202 | return list; 203 | } 204 | 205 | public void addManyToManyKey(Column fk, Column pk) 206 | { 207 | manyToManyHash.put(fk, pk); 208 | } 209 | 210 | public int countColumns() 211 | { 212 | return cols.size(); 213 | } 214 | 215 | public int countPrimaryKeys() 216 | { 217 | return priKey.size(); 218 | } 219 | 220 | public boolean hasPrimaryKey() 221 | { 222 | return countPrimaryKeys() > 0; 223 | } 224 | 225 | public int countImportedKeys() 226 | { 227 | return importedKeys.size(); 228 | } 229 | 230 | public boolean hasImportedKeys() 231 | { 232 | return countImportedKeys() > 0; 233 | } 234 | 235 | public int countForeignKeys() 236 | { 237 | return foreignKeys.size(); 238 | } 239 | 240 | public boolean hasForeignKeys() 241 | { 242 | return countForeignKeys() > 0; 243 | } 244 | 245 | public void addForeignKey(Column col) 246 | { 247 | if (foreignKeys.contains(col) == false) 248 | foreignKeys.add(col); 249 | } 250 | 251 | public Column[] getForeignKeys() 252 | { 253 | return (Column[])foreignKeys.toArray(new Column[0]); 254 | } 255 | 256 | public boolean isForeignKey(Column col) 257 | { 258 | return foreignKeys.contains(col); 259 | } 260 | 261 | public Table[] getLinkedTables() 262 | { 263 | Vector vector = new Vector(); 264 | 265 | for (int iIndex = 0; iIndex < importedKeys.size(); iIndex++) 266 | { 267 | Column column = (Column) importedKeys.get(iIndex); 268 | if (column.getTableName().equals(getName()) == false) 269 | { 270 | Table pTableToAdd = column.getTable(); 271 | if (vector.contains(pTableToAdd) == false) 272 | vector.add(pTableToAdd); 273 | } 274 | } 275 | 276 | for (int iIndex = 0; iIndex < foreignKeys.size(); iIndex++) 277 | { 278 | Column column = (Column) foreignKeys.get(iIndex); 279 | column = column.getForeignColumn(); 280 | if (column.getTableName().equals(getName()) == false) 281 | { 282 | Table pTableToAdd = column.getTable(); 283 | if (vector.contains(pTableToAdd) == false) 284 | vector.add(pTableToAdd); 285 | } 286 | } 287 | return (Table[])vector.toArray(new Table[0]); 288 | } 289 | 290 | private Table[] getImportedTablesFromVector(Vector keys) 291 | { 292 | Vector vector = new Vector(); 293 | for (int iIndex = 0; iIndex < keys.size(); iIndex++) 294 | { 295 | Column column = (Column) keys.get(iIndex); 296 | if (column.getTableName().equals(getName()) == false) 297 | { 298 | Table pTableToAdd = column.getTable(); 299 | if (vector.contains(pTableToAdd) == false) 300 | vector.add(pTableToAdd); 301 | } 302 | } 303 | return (Table[])vector.toArray(new Table[0]); 304 | } 305 | 306 | public Table[] getImportedTables() 307 | { 308 | return getImportedTablesFromVector(importedKeys); 309 | } 310 | 311 | public Table[] getForeignTables() 312 | { 313 | return getImportedTablesFromVector(foreignKeys); 314 | } 315 | 316 | public String[] getLinkedPackages() 317 | { 318 | Vector vector = new Vector(); 319 | Table[] linkedTables = getLinkedTables(); 320 | for (int iIndex = 0; iIndex < linkedTables.length; iIndex++) 321 | { 322 | if (vector.contains(linkedTables[iIndex].getPackage()) == false) 323 | vector.add(linkedTables[iIndex].getPackage()); 324 | } 325 | return (String[])vector.toArray(new String[0]); 326 | } 327 | 328 | public String getPackage() 329 | { 330 | String basePackage = CodeWriter.getProperty("mgrwriter.package"); 331 | // iterate in the subpackage.X.names 332 | // starting at 1 333 | int iterating = 1; 334 | while(true) 335 | { 336 | String tablesProperty = "subpackage." + iterating + ".tables"; 337 | String packageNameProperty = "subpackage." + iterating + ".name"; 338 | String tables[] = CodeWriter.getPropertyExploded(tablesProperty); 339 | for (int i = 0; i < tables.length; i ++) 340 | { 341 | if (getName().equalsIgnoreCase(tables[i])) 342 | { 343 | String packageName = CodeWriter.getProperty(packageNameProperty); 344 | if (packageName == null) 345 | return basePackage; 346 | return basePackage + "." + packageName; 347 | } 348 | } 349 | iterating ++; 350 | 351 | // no tables found ? 352 | // ok stop iterating 353 | if (tables.length == 0) 354 | break; 355 | } 356 | return basePackage; 357 | } 358 | 359 | public String getPackagePath() 360 | { 361 | return getPackage().replace('.', '/'); 362 | } 363 | 364 | public Column[] getColumnsFor(String type) 365 | { 366 | Vector vector = new Vector(); 367 | for (int i = 0; i < cols.size(); i++) 368 | { 369 | Column c = (Column)cols.get(i); 370 | if (c.columnFor(type)) 371 | vector.add(c); 372 | } 373 | return (Column[])vector.toArray(new Column[0]); 374 | } 375 | 376 | } 377 | -------------------------------------------------------------------------------- /sql2java-maven-plugin/src/main/java/net/sourceforge/sql2java/UserCodeParser.java: -------------------------------------------------------------------------------- 1 | //$Id: UserCodeParser.java,v 1.1 2005/10/12 18:44:24 framiere Exp $ 2 | 3 | package net.sourceforge.sql2java; 4 | 5 | import java.io.*; 6 | import java.util.*; 7 | 8 | /** 9 | * Parses an existing source file for special sql2code comment blocks. 10 | *
11 | * Stores the source code that it finds in between those blocks in a 12 | * hashtable. This allows CodeWriter classes to rewrite existing files 13 | * while preserving code written by the user. 14 | * 15 | * @author James Cooper 16 | * @version $Id: UserCodeParser.java,v 1.1 2005/10/12 18:44:24 framiere Exp $ 17 | */ 18 | public class UserCodeParser { 19 | 20 | private static final String START = "// "; 21 | private static final String BLOCK_BEGIN = "+ "; 22 | private static final String BLOCK_END = "- "; 23 | 24 | private String LINE_SEP = System.getProperty("line.separator"); 25 | private Hashtable codeHash; 26 | private String filename; 27 | private boolean isNew; 28 | 29 | /** 30 | * Constructs a new parser, and tells the parser to try to load the 31 | * given filename. 32 | *
33 | * If the file does not exist, the parser will simply initialize a 34 | * new hashtable internally, and the get methods on the parser will 35 | * return new comment blocks (with nothing in between them). 36 | * 37 | * @param filename Full path to the existing file to parse. 38 | * @throws Exception if the existing file exists, but cannot be read, 39 | * or if there is an error while reading the file 40 | */ 41 | public UserCodeParser(String filename) throws Exception { 42 | parse(filename); 43 | } 44 | 45 | /** 46 | * Returns the filename associated with this parser. 47 | */ 48 | public String getFilename() { return filename; } 49 | 50 | /** 51 | * Returns true if the file to parse did not exist. 52 | */ 53 | public boolean isNew() { return isNew; } 54 | 55 | /** 56 | * Parses the file passed in. 57 | */ 58 | public void parse(String filename) throws Exception { 59 | codeHash = new Hashtable(); 60 | boolean inBlock = false; 61 | String blockName = null; 62 | StringBuffer code = new StringBuffer(); 63 | isNew = true; 64 | 65 | File file = new File(filename); 66 | if(file.exists()) { 67 | isNew = false; 68 | BufferedReader reader = new BufferedReader(new FileReader(file)); 69 | String line = reader.readLine(); 70 | while(line != null) { 71 | if(inBlock) code.append(line).append(LINE_SEP); 72 | 73 | if(line.indexOf(START) != -1) { 74 | if(inBlock) { 75 | if(line.equals(START + blockName + BLOCK_END)) { 76 | 77 | // Done parsing block. Store it 78 | codeHash.put(blockName, code.toString()); 79 | inBlock = false; 80 | } 81 | } 82 | else { 83 | blockName = parseName(line); 84 | if(!blockName.equals("")) { 85 | inBlock = true; 86 | code.setLength(0); 87 | code.append(line).append(LINE_SEP); 88 | } 89 | } 90 | } 91 | 92 | line = reader.readLine(); 93 | } 94 | reader.close(); 95 | } 96 | } 97 | 98 | private String parseName(String line) { 99 | int startPos = line.indexOf(START); 100 | if(startPos == -1) return ""; 101 | startPos += START.length(); 102 | 103 | if(startPos >= (line.length() + 1)) return ""; 104 | 105 | int endPos = line.indexOf(BLOCK_BEGIN, startPos); 106 | if(endPos == -1) return ""; 107 | else { 108 | String name = line.substring(startPos, endPos); 109 | return name; 110 | } 111 | } 112 | 113 | /** 114 | * Returns true if there is a block with the given name in the 115 | * existing file that was parsed, otherwise returns false. 116 | * 117 | * @param name Name of the code block to check for. 118 | */ 119 | public boolean hasBlock(String name) { 120 | return codeHash.get(name) != null; 121 | } 122 | 123 | /** 124 | * Returns the comment+code block associated with this name. 125 | *
126 | * If the name is not found in the parsed file, this returns a new 127 | * comment block with no code inside it. 128 | * 129 | * @param name Name of the code block to return. 130 | */ 131 | public String getBlock(String name) { 132 | String code = null; 133 | if (name != null) code = (String)codeHash.get(name); 134 | if(code == null) { 135 | code = generateNewBlock(name); 136 | codeHash.put(name, code); 137 | } 138 | return code; 139 | } 140 | 141 | /** 142 | * Returns an array of the block names parsed in the existing file. 143 | *
144 | * If the file did not exist, or if there are no blocks in the file, 145 | * a zero length array is returned. 146 | */ 147 | public String[] getBlockNames() { 148 | String list[] = new String[codeHash.size()]; 149 | int i = 0; 150 | for(Enumeration e = codeHash.keys(); e.hasMoreElements(); ) { 151 | list[i++] = (String)e.nextElement(); 152 | } 153 | 154 | return list; 155 | } 156 | 157 | /** 158 | * Generates a new code block with this name. 159 | */ 160 | private String generateNewBlock(String name) { 161 | StringBuffer str = new StringBuffer(512); 162 | str.append(START); 163 | str.append(name); 164 | str.append(BLOCK_BEGIN); 165 | str.append(LINE_SEP).append(LINE_SEP); 166 | str.append(START); 167 | str.append(name); 168 | str.append(BLOCK_END); 169 | 170 | return str.toString(); 171 | } 172 | } 173 | -------------------------------------------------------------------------------- /sql2java-maven-plugin/src/main/java/net/sourceforge/sql2java/ant/GenerationTask.java: -------------------------------------------------------------------------------- 1 | //$Id: GenerationTask.java,v 1.1 2005/10/12 18:44:24 framiere Exp $ 2 | 3 | package net.sourceforge.sql2java.ant; 4 | 5 | import org.apache.tools.ant.BuildException; 6 | import org.apache.tools.ant.Task; 7 | import net.sourceforge.sql2java.*; 8 | 9 | public class GenerationTask extends Task { 10 | private String propertyFile; 11 | 12 | // The method executing the task 13 | public void execute() throws BuildException 14 | { 15 | System.out.println("GenerationTask: " + propertyFile); 16 | String args[] = new String[]{propertyFile}; 17 | Main.main(args); 18 | } 19 | 20 | // The setter for the "propertyFile" attribute 21 | public void setPropertyFile(String msg) { 22 | this.propertyFile = msg; 23 | } 24 | } -------------------------------------------------------------------------------- /sql2java-maven-plugin/src/main/java/net/sourceforge/sql2java/ant/SchemaCheckTask.java: -------------------------------------------------------------------------------- 1 | //$Id: SchemaCheckTask.java,v 1.1 2005/10/12 18:44:24 framiere Exp $ 2 | 3 | package net.sourceforge.sql2java.ant; 4 | 5 | import java.util.*; 6 | 7 | import net.sourceforge.sql2java.*; 8 | 9 | import org.apache.tools.ant.BuildException; 10 | import org.apache.tools.ant.Task; 11 | 12 | public class SchemaCheckTask extends Task { 13 | private String propertyFile; 14 | 15 | // The method executing the task 16 | public void execute() throws BuildException 17 | { 18 | System.out.println("SchemaCheckTask: " + propertyFile); 19 | String args[] = new String[] {propertyFile}; 20 | Map map = new HashMap(); 21 | map.put("check.only.database", "true"); 22 | Main.main(args, map); 23 | } 24 | 25 | // The setter for the "propertyFile" attribute 26 | public void setPropertyFile(String msg) { 27 | this.propertyFile = msg; 28 | } 29 | } -------------------------------------------------------------------------------- /sql2java-maven-plugin/src/main/java/net/sourceforge/sql2java/ant/TableGenerationTask.java: -------------------------------------------------------------------------------- 1 | //$Id: TableGenerationTask.java,v 1.1 2005/10/12 18:44:24 framiere Exp $ 2 | 3 | package net.sourceforge.sql2java.ant; 4 | 5 | import java.util.*; 6 | 7 | import net.sourceforge.sql2java.*; 8 | 9 | import org.apache.tools.ant.BuildException; 10 | import org.apache.tools.ant.Task; 11 | 12 | public class TableGenerationTask extends Task { 13 | private String propertyFile; 14 | private String tables; 15 | 16 | // The method executing the task 17 | public void execute() throws BuildException 18 | { 19 | System.out.println("TableGenerationTask: " + propertyFile); 20 | String args[] = new String[]{propertyFile}; 21 | Map map = new HashMap(); 22 | map.put("mgrwriter.include", tables); 23 | Main.main(args, map); 24 | } 25 | 26 | // The setter for the "propertyFile" attribute 27 | public void setPropertyFile(String msg) { 28 | this.propertyFile = msg; 29 | } 30 | 31 | // The setter for the "table" attribute 32 | public void setTables(String msg) { 33 | this.tables = msg; 34 | } 35 | } -------------------------------------------------------------------------------- /sql2java-maven-plugin/src/main/java/net/sourceforge/sql2java/ant/UtilsGenerationTask.java: -------------------------------------------------------------------------------- 1 | //$Id: UtilsGenerationTask.java,v 1.1 2005/10/12 18:44:24 framiere Exp $ 2 | 3 | package net.sourceforge.sql2java.ant; 4 | 5 | import java.util.*; 6 | 7 | import net.sourceforge.sql2java.*; 8 | 9 | import org.apache.tools.ant.BuildException; 10 | import org.apache.tools.ant.Task; 11 | 12 | public class UtilsGenerationTask extends Task { 13 | private String propertyFile; 14 | 15 | // The method executing the task 16 | public void execute() throws BuildException 17 | { 18 | System.out.println("UtilsGenerationTask: " + propertyFile); 19 | String args[] = new String[] {propertyFile}; 20 | Map map = new HashMap(); 21 | map.put("check.database", "false"); 22 | map.put("write.only.per.schema.templates", "true"); 23 | Main.main(args, map); 24 | } 25 | 26 | // The setter for the "propertyFile" attribute 27 | public void setPropertyFile(String msg) { 28 | this.propertyFile = msg; 29 | } 30 | } -------------------------------------------------------------------------------- /sql2java-maven-plugin/src/main/java/net/sourceforge/sql2java/maven/AbstractDbMojo.java: -------------------------------------------------------------------------------- 1 | package net.sourceforge.sql2java.maven; 2 | 3 | import org.apache.maven.plugin.AbstractMojo; 4 | import org.apache.maven.plugins.annotations.Parameter; 5 | 6 | /** 7 | * Common abstract Mojo for plugins with db props. 8 | * @author garth 9 | */ 10 | public abstract class AbstractDbMojo extends AbstractMojo { 11 | 12 | /** 13 | * JDBC driver class name. 14 | */ 15 | @Parameter(property = "driver", defaultValue = "org.hsqldb.jdbcDriver", required = true) 16 | protected String driver; 17 | 18 | /** 19 | * Database connection string. 20 | */ 21 | @Parameter(property = "url", defaultValue = "jdbc:hsqldb:file:${project.build.directory}/databases/test", required = true) 22 | protected String url; 23 | 24 | /** 25 | * Database connection user name. 26 | */ 27 | @Parameter(property = "user", defaultValue = "SA", required = true) 28 | protected String user; 29 | 30 | /** 31 | * Database connection user password. 32 | */ 33 | @Parameter(property = "password", defaultValue = "") 34 | protected String password; 35 | 36 | /** 37 | * Database catalog 38 | */ 39 | @Parameter(property = "catalog") 40 | protected String catalog; 41 | 42 | /** 43 | * Database schema 44 | */ 45 | @Parameter(property = "schema", defaultValue = "PUBLIC") 46 | protected String schema; 47 | 48 | } 49 | -------------------------------------------------------------------------------- /sql2java-maven-plugin/src/main/java/net/sourceforge/sql2java/maven/Sql2JavaMojo.java: -------------------------------------------------------------------------------- 1 | package net.sourceforge.sql2java.maven; 2 | 3 | import java.io.File; 4 | import java.io.FileInputStream; 5 | import java.io.IOException; 6 | import java.util.ArrayList; 7 | import java.util.Properties; 8 | import java.util.StringTokenizer; 9 | import net.sourceforge.sql2java.*; 10 | import org.apache.maven.plugin.AbstractMojo; 11 | import org.apache.maven.plugin.MojoExecutionException; 12 | import org.apache.maven.plugins.annotations.Mojo; 13 | import org.apache.maven.plugins.annotations.Parameter; 14 | 15 | /** 16 | * Goal which uses sql2java to generate Java files from a SQL database. 17 | * @author garth 18 | */ 19 | @Mojo(name="sql2java", requiresDirectInvocation=true) 20 | public class Sql2JavaMojo extends AbstractDbMojo { 21 | 22 | /** 23 | * The working directory where the generated Java source files are created. 24 | */ 25 | @Parameter(property="outputDirectory", defaultValue="${project.build.directory}/generated-sources/sql2java", required=true) 26 | private File outputDirectory; 27 | 28 | protected File getOutputDirectory() { 29 | return outputDirectory; 30 | } 31 | 32 | /** 33 | * The location of the properties file. 34 | */ 35 | @Parameter(property="propertiesFile", defaultValue="${project.basedir}/src/main/resources/sql2java.properties", required=true) 36 | private File propertiesFile; 37 | 38 | protected File getPropertiesFile() { 39 | return propertiesFile; 40 | } 41 | 42 | /** 43 | * Database schema alias 44 | */ 45 | @Parameter(property="schemaAlias", defaultValue="test") 46 | private String schemaAlias; 47 | 48 | /** 49 | * Package name 50 | */ 51 | @Parameter(property="packageName", required=true) 52 | private String packageName; 53 | 54 | /** 55 | * Class prefix 56 | */ 57 | @Parameter(property="classPrefix", required=false) 58 | private String classPrefix; 59 | 60 | public void execute() throws MojoExecutionException { 61 | File f = outputDirectory; 62 | if ( !f.exists() ) { 63 | f.mkdirs(); 64 | } 65 | 66 | if ( !propertiesFile.exists() ) { 67 | throw new MojoExecutionException(propertiesFile.getName() + " doesn't exist!"); 68 | } 69 | 70 | //properties already here ? 71 | Properties prop = new Properties(); 72 | CodeWriter writer = null; 73 | try { 74 | prop.load(new FileInputStream(propertiesFile)); 75 | Database db = new Database(); 76 | db.setDriver(driver); 77 | db.setUrl(url); 78 | db.setUsername(user); 79 | db.setPassword(password); 80 | db.setCatalog(catalog); 81 | db.setSchema(schema); 82 | //db.setSchemaAlias(schemaAlias); 83 | db.setTableNamePattern(getProperty(prop, "jdbc.tablenamepattern")); 84 | 85 | if ("false".equalsIgnoreCase(getProperty(prop, "jdbc.oracle.retrieve.remarks"))) 86 | db.setOracleRetrieveRemarks(false); 87 | else 88 | db.setOracleRetrieveRemarks(true); 89 | 90 | String tt = getProperty(prop, "jdbc.tabletypes", "TABLE"); 91 | StringTokenizer st = new StringTokenizer(tt, ",; \t"); 92 | ArrayList al = new ArrayList(); 93 | 94 | while(st.hasMoreTokens()) { 95 | al.add(((String)st.nextToken()).trim()); 96 | } 97 | 98 | db.setTableTypes((String[])al.toArray(new String[al.size()])); 99 | 100 | db.load(); 101 | 102 | //HACK 103 | if (packageName != null) prop.setProperty("mgrwriter.package", packageName); 104 | if (classPrefix != null) prop.setProperty("mgrwriter.classprefix", classPrefix); 105 | writer = new CodeWriter(db, prop); 106 | // override destdir if given 107 | writer.setUseLibrary("net.sourceforge.sql2java.lib"); 108 | writer.setDestinationFolder(outputDirectory.getPath()); 109 | writer.process(); 110 | } catch(Exception e) { 111 | throw new MojoExecutionException("Error executing plugin", e); 112 | } finally { 113 | if (writer != null) { 114 | writer.cleanup(); 115 | } 116 | } 117 | 118 | } 119 | 120 | public static String getProperty(Properties prop, String key) 121 | { 122 | String s = prop.getProperty(key); 123 | return s!=null?s.trim():s; 124 | } 125 | 126 | /** 127 | * helper method with default values 128 | */ 129 | public static String getProperty(Properties prop, String key, String default_val) 130 | { 131 | String s = getProperty(prop, key); 132 | if (s == null) 133 | return default_val; 134 | return s; 135 | } 136 | 137 | /** 138 | * is the given code in the string array ? 139 | */ 140 | public static boolean isInArray(String[] ar, String code) 141 | { 142 | if (ar == null) 143 | return false; 144 | for (int i = 0; i < ar.length; i ++) 145 | { 146 | if (code.equalsIgnoreCase(ar[i])) 147 | return true; 148 | } 149 | return false; 150 | } 151 | 152 | } 153 | -------------------------------------------------------------------------------- /sql2java-maven-plugin/src/main/java/net/sourceforge/sql2java/maven/SqlFileMojo.java: -------------------------------------------------------------------------------- 1 | package net.sourceforge.sql2java.maven; 2 | 3 | import java.io.File; 4 | import java.io.FilenameFilter; 5 | import java.io.IOException; 6 | import java.sql.Connection; 7 | import java.sql.DriverManager; 8 | import java.sql.Statement; 9 | import java.sql.SQLException; 10 | import java.util.Arrays; 11 | import net.sourceforge.sql2java.*; 12 | import org.apache.maven.plugin.MojoExecutionException; 13 | import org.apache.maven.plugins.annotations.Mojo; 14 | import org.apache.maven.plugins.annotations.Parameter; 15 | import org.hsqldb.cmdline.SqlFile; 16 | 17 | /** 18 | * Goal which uses hsqldb's SqlFile to source scripts to a db. 19 | * @author garth 20 | */ 21 | @Mojo(name="sqlfile", requiresDirectInvocation=true) 22 | public class SqlFileMojo extends AbstractDbMojo { 23 | 24 | /** 25 | * Wipe all data and table definitions if they already exist? 26 | */ 27 | @Parameter(property="deleteData", defaultValue="false") 28 | private boolean deleteData; 29 | 30 | /** 31 | * The script directory. 32 | */ 33 | @Parameter(property="scriptDirectory", defaultValue="${project.basedir}/src/main/sql", required=true) 34 | private File scriptDirectory; 35 | 36 | protected File getScriptDirectory() { 37 | return scriptDirectory; 38 | } 39 | 40 | public void execute() throws MojoExecutionException { 41 | Connection connection = null; 42 | try { 43 | Class.forName(driver); 44 | connection = DriverManager.getConnection(url, user, password); 45 | 46 | //deleteData? 47 | //hsql:DROP SCHEMA PUBLIC CASCADE 48 | 49 | File[] files = scriptDirectory.listFiles(new FilenameFilter() { 50 | public boolean accept(File dir, String name) { 51 | return name.toLowerCase().endsWith(".sql"); 52 | } 53 | }); 54 | Arrays.sort(files); 55 | for (File file : files) { 56 | getLog().info(String.format("Processing %s", file)); 57 | SqlFile sqlFile = new SqlFile(file, null, false); 58 | sqlFile.setConnection(connection); 59 | sqlFile.execute(); 60 | } 61 | } catch (Exception e) { 62 | getLog().error("", e); 63 | } finally { 64 | if (connection != null) { 65 | try { 66 | //HACK 67 | if (url.contains("jdbc:hsqldb:file")) { 68 | Statement statement = connection.createStatement(); 69 | statement.executeUpdate("SHUTDOWN"); 70 | statement.close(); 71 | } 72 | } catch (SQLException ignore) {} 73 | try { 74 | connection.close(); 75 | } catch (SQLException ignore) {} 76 | } 77 | } 78 | } 79 | 80 | } 81 | -------------------------------------------------------------------------------- /sql2java-maven-plugin/src/main/resources/bean.java.vm: -------------------------------------------------------------------------------- 1 | ##$Id: bean.java.vm,v 1.8 2005/10/17 09:09:59 framiere Exp $ 2 | #parse( "header.include.vm" ) 3 | #parse( "table.variables.include.vm" ) 4 | $codewriter.setCurrentJavaFilename("$table.getPackage()", "${beanClass}.java") 5 | package $table.getPackage(); 6 | 7 | import $pkg.*; 8 | 9 | import java.io.Serializable; 10 | import java.util.Collections; 11 | import java.util.Map; 12 | import java.util.HashMap; 13 | #if ($useLib) 14 | import $libPath.*; 15 | #end 16 | 17 | /** 18 | * $beanClass is a mapping of $table.getName() Table. 19 | #if ( $table.getRemarks().length() > 0 ) 20 | *
Meta Data Information (in progress): 21 | *

    22 | *
  • comments: $table.getRemarks()
  • 23 | *
24 | #end 25 | */ 26 | public class $beanClass 27 | #if ($extendsClass) 28 | extends $extendsClass 29 | #end 30 | implements Serializable, DaoBean 31 | #if ($implementsClasses) 32 | #foreach( $implements in $implementsClasses )$implements#end 33 | #end 34 | { 35 | #foreach ( $column in $columns ) 36 | #set( $columnfield = $strUtil.getVarName($column)) 37 | 38 | private $column.getJavaType() $strUtil.getVarName($column); 39 | private boolean $strUtil.getModifiedVarName( $column ) = false; 40 | private boolean $strUtil.getInitializedVarName( $column ) = false; 41 | 42 | #end 43 | private boolean _isNew = true; 44 | 45 | /** 46 | * Do not use this constructor directly, please use the factory method 47 | * available in the associated manager. 48 | */ 49 | $beanClass() 50 | { 51 | } 52 | 53 | #foreach ($column in $columns) 54 | /** 55 | * Getter method for $strUtil.getVarName($column). 56 | *
57 | #if ( $column.isPrimaryKey() ) 58 | * PRIMARY KEY.
59 | #end 60 | * Meta Data Information (in progress): 61 | *
    62 | *
  • full name: $column.getFullName() 63 | #if ( $column.getPointsTo() ) 64 | *
  • foreign key: ${column.PointsTo.TableName}.${column.PointsTo.getName()} 65 | #end 66 | #if ( $column.getRemarks().length() > 0 ) 67 | *
  • comments: $column.getRemarks() 68 | #end 69 | #if ( $column.DefaultValue.length() > 0 ) 70 | *
  • default value: $column.DefaultValue 71 | #end 72 | *
  • column size: $column.getSize() 73 | *
  • jdbc type returned by the driver: $column.getJavaTypeAsTypeName() 74 | *
75 | * 76 | * @return the value of $strUtil.getVarName($column) 77 | */ 78 | public $column.getJavaType() $strUtil.getGetMethod($column)() 79 | { 80 | return $strUtil.getVarName($column); 81 | } 82 | 83 | /** 84 | * Setter method for $strUtil.getVarName($column). 85 | *
86 | #if ( $column.hasCompareTo() ) 87 | * The new value is set only if compareTo() says it is different, 88 | * or if one of either the new value or the current value is null. 89 | * In case the new value is different, it is set and the field is marked as 'modified'. 90 | #else 91 | * Attention, there will be no comparison with current value which 92 | * means calling this method will mark the field as 'modified' in all cases. 93 | #end 94 | * 95 | * @param newVal the new value to be assigned to $strUtil.getVarName($column) 96 | */ 97 | public void ${strUtil.getSetMethod($column)}($column.getJavaType() newVal) 98 | { 99 | #if ($column.hasCompareTo()) 100 | if ((newVal != null && this.$strUtil.getVarName($column) != null && (newVal.compareTo(this.$strUtil.getVarName($column)) == 0)) || 101 | (newVal == null && this.$strUtil.getVarName($column) == null && $strUtil.getInitializedVarName($column))) { 102 | return; 103 | } 104 | #elseif ( $column.useEqualsInSetter() ) 105 | if ((newVal != null && this.$strUtil.getVarName($column) != null && newVal.equals(this.$strUtil.getVarName($column))) || 106 | (newVal == null && this.$strUtil.getVarName($column) == null && $strUtil.getInitializedVarName($column))) { 107 | return; 108 | } 109 | #end 110 | this.$strUtil.getVarName($column) = newVal; 111 | $strUtil.getModifiedVarName($column) = true; 112 | $strUtil.getInitializedVarName($column) = true; 113 | } 114 | 115 | #if ( $strUtil.hasPrimaryType($column) ) 116 | /** 117 | * Setter method for $strUtil.getVarName($column). 118 | *
119 | * Convenient for those who do not want to deal with Objects for primary types. 120 | * 121 | * @param newVal the new value to be assigned to $strUtil.getVarName($column) 122 | */ 123 | public void $strUtil.getSetMethod($column)($strUtil.getJavaPrimaryType($column) newVal) 124 | { 125 | $strUtil.getSetMethod($column)(new $column.getJavaType()(newVal)); 126 | } 127 | 128 | #end 129 | /** 130 | * Determines if the $strUtil.getVarName($column) has been modified. 131 | * 132 | * @return true if the field has been modified, false if the field has not been modified 133 | */ 134 | public boolean $strUtil.getModifiedMethod($column)() 135 | { 136 | return $strUtil.getModifiedVarName($column); 137 | } 138 | 139 | /** 140 | * Determines if the $strUtil.getVarName($column) has been initialized. 141 | *
142 | * It is useful to determine if a field is null on purpose or just because it has not been initialized. 143 | * 144 | * @return true if the field has been initialized, false otherwise 145 | */ 146 | public boolean $strUtil.getInitializedMethod($column)() 147 | { 148 | return $strUtil.getInitializedVarName($column); 149 | } 150 | 151 | #end 152 | /** 153 | * Determines if the current object is new. 154 | * 155 | * @return true if the current object is new, false if the object is not new 156 | */ 157 | public boolean isNew() 158 | { 159 | return _isNew; 160 | } 161 | 162 | /** 163 | * Specifies to the object if it has been set as new. 164 | * 165 | * @param isNew the boolean value to be assigned to the isNew field 166 | */ 167 | public void isNew(boolean isNew) 168 | { 169 | this._isNew = isNew; 170 | } 171 | 172 | /** 173 | * Determines if the object has been modified since the last time this method was called. 174 | *
175 | * We can also determine if this object has ever been modified since its creation. 176 | * 177 | * @return true if the object has been modified, false if the object has not been modified 178 | */ 179 | public boolean isModified() 180 | { 181 | return #foreach ( $column in $columns )#if ( $velocityCount == 1 )$strUtil.getModifiedVarName($column)#else || 182 | $strUtil.getModifiedVarName($column)#end#end; 183 | } 184 | 185 | /** 186 | * Resets the object modification status to 'not modified'. 187 | */ 188 | public void resetIsModified() 189 | { 190 | #foreach ( $column in $columns ) 191 | $strUtil.getModifiedVarName($column) = false; 192 | #end 193 | } 194 | 195 | /** 196 | * Copies the passed bean into the current bean. 197 | * 198 | * @param bean the bean to copy into the current bean 199 | */ 200 | public void copy($beanClass bean) 201 | { 202 | #foreach ( $column in $columns ) 203 | $strUtil.getSetMethod($column)(bean.$strUtil.getGetMethod($column)()); 204 | #end 205 | } 206 | 207 | /** 208 | * Returns the object string representation. 209 | * 210 | * @return the object as a string 211 | */ 212 | public String toString() 213 | { 214 | return toString("\n"); 215 | } 216 | 217 | /** 218 | * Returns the object string representation. 219 | * @param delim use the provided delimiter between fields. 220 | * @return the object as a string 221 | */ 222 | public String toString(String delim) 223 | { 224 | return "[$tablename] " 225 | #foreach ( $column in $columns ) 226 | + delim + " - $column.getFullName() = " + ($strUtil.getInitializedVarName($column) ? ("[" + ($strUtil.getVarName($column) == null ? null : ${strUtil.getVarName($column)}.toString()) + "]") : "not initialized") + "" 227 | #end 228 | ; 229 | } 230 | 231 | /** 232 | * return a dictionary of the object 233 | */ 234 | public Map getDictionary() 235 | { 236 | Map dictionary = new HashMap(); 237 | #foreach ( $column in $columns ) 238 | dictionary.put("$column.getName().toLowerCase()", ${strUtil.getGetMethod($column)}()); 239 | #end 240 | return Collections.unmodifiableMap(dictionary); 241 | } 242 | 243 | /** 244 | * return a dictionary of the pk columns 245 | #if ( $table.countPrimaryKeys() == 0) 246 | * no primary key, the regular dictionary is returned 247 | #end 248 | */ 249 | public Map getPkDictionary() 250 | { 251 | #if ( $table.countPrimaryKeys() == 0) 252 | return getDictionary(); 253 | #else 254 | Map dictionary = new HashMap(); 255 | #foreach ( $column in $primaryKeys ) 256 | dictionary.put("$column.getName().toLowerCase()", ${strUtil.getGetMethod($column)}()); 257 | #end 258 | return Collections.unmodifiableMap(dictionary); 259 | #end 260 | } 261 | } 262 | -------------------------------------------------------------------------------- /sql2java-maven-plugin/src/main/resources/daobean.java.vm: -------------------------------------------------------------------------------- 1 | ##$Id: generated.bean.java.vm,v 1.1 2005/10/12 12:37:58 framiere Exp $ 2 | #parse( "header.include.vm" ) 3 | $codewriter.setCurrentJavaFilename($pkg, "DaoBean.java") 4 | package $pkg; 5 | 6 | import java.util.Map; 7 | 8 | public interface DaoBean 9 | { 10 | public boolean isNew(); 11 | public boolean isModified(); 12 | public void resetIsModified(); 13 | public Map getDictionary(); 14 | public Map getPkDictionary(); 15 | public String toString(String delim); 16 | } 17 | -------------------------------------------------------------------------------- /sql2java-maven-plugin/src/main/resources/daomanager.java.vm: -------------------------------------------------------------------------------- 1 | ##$Id: global.manager.java.vm,v 1.3 2005/10/10 20:11:46 framiere Exp $ 2 | #parse( "header.include.vm" ) 3 | $codewriter.setCurrentJavaFilename($pkg, "DaoManager.java") 4 | package $pkg; 5 | 6 | import java.sql.PreparedStatement; 7 | import java.sql.ResultSet; 8 | import java.sql.SQLException; 9 | import java.util.List; 10 | 11 | /** 12 | * Data access manager. 13 | */ 14 | public interface DaoManager 15 | { 16 | public T createBean(); 17 | public String getTableName(); 18 | public T loadByPrimaryKey(Integer id) throws SQLException; 19 | public int deleteByPrimaryKey(Integer id) throws SQLException; 20 | public List loadAll() throws SQLException; 21 | public List loadAll(int startRow, int numRows) throws SQLException; 22 | public List loadByWhere(String where) throws SQLException; 23 | public List loadByWhere(String where, Object... fields) throws SQLException; 24 | public List loadByWhere(String where, int startRow, int numRows) throws SQLException; 25 | public T loadUniqueByWhere(String where) throws SQLException; 26 | public T loadUniqueByWhere(String where, Object... fields) throws SQLException; 27 | public int deleteAll() throws SQLException; 28 | public int deleteByWhere(String where) throws SQLException; 29 | public int deleteByWhere(String where, Object... fields) throws SQLException; 30 | public T save(T bean) throws SQLException; 31 | public T insert(T bean) throws SQLException; 32 | public T insert(T bean, boolean orUpdate) throws SQLException; 33 | public T insert(T bean, boolean orUpdate, boolean delayed) throws SQLException; 34 | public T update(T bean) throws SQLException; 35 | public List save(List beans) throws SQLException; 36 | public List insert(List beans) throws SQLException; 37 | public List update(List beans) throws SQLException; 38 | public T loadUniqueUsingTemplate(T bean) throws SQLException; 39 | public List loadUsingTemplate(T bean) throws SQLException; 40 | public List loadUsingTemplate(T bean, int startRow, int numRows) throws SQLException; 41 | public List loadUsingTemplate(T bean, int startRow, int numRows, int searchType) throws SQLException; 42 | public int deleteUsingTemplate(T bean) throws SQLException; 43 | public int countAll() throws SQLException; 44 | public int countWhere(String where) throws SQLException; 45 | public int countWhere(String where, Object... fields) throws SQLException; 46 | public int countUsingTemplate(T bean) throws SQLException; 47 | public int countUsingTemplate(T bean, int startRow, int numRows) throws SQLException; 48 | public int countUsingTemplate(T bean, int startRow, int numRows, int searchType) throws SQLException; 49 | public List decodeResultSet(ResultSet rs, int startRow, int numRows) throws SQLException; 50 | public T decodeRow(ResultSet rs) throws SQLException; 51 | public T metaDataDecodeRow(ResultSet rs) throws SQLException; 52 | public List loadByPreparedStatement(PreparedStatement ps) throws SQLException; 53 | public List loadByPreparedStatement(PreparedStatement ps, int startRow, int numRows) throws SQLException; 54 | } 55 | -------------------------------------------------------------------------------- /sql2java-maven-plugin/src/main/resources/database.java.vm: -------------------------------------------------------------------------------- 1 | ##$Id: global.manager.java.vm,v 1.3 2005/10/10 20:11:46 framiere Exp $ 2 | #parse( "header.include.vm" ) 3 | #set( $className = $strUtil.convertName($schema) ) 4 | $codewriter.setCurrentJavaFilename($pkg, "${className}Database.java") 5 | package $pkg; 6 | 7 | import javax.sql.DataSource; 8 | import org.slf4j.Logger; 9 | import org.slf4j.LoggerFactory; 10 | #if ($useLib) 11 | import $libPath.*; 12 | #end 13 | 14 | /** 15 | * ${strUtil.convertName($db.schema)}Database is a mapping of the $db.schema schema. 16 | */ 17 | public class ${strUtil.convertName($db.schema)}Database extends Database { 18 | 19 | public ${className}Database(DataSource dataSource) { 20 | super(dataSource); 21 | #foreach ( $table in $tables ) 22 | this.$strUtil.getManagerObjectName($table) = new $strUtil.getManagerClass($table)(dataSource); 23 | registerManager(this.$strUtil.getManagerObjectName($table)); 24 | #end 25 | } 26 | 27 | protected DataSource dataSource; 28 | #foreach ( $table in $tables ) 29 | protected $strUtil.getManagerClass($table) $strUtil.getManagerObjectName($table); 30 | #end 31 | 32 | #foreach ( $table in $tables ) 33 | public $strUtil.getManagerClass($table) get$strUtil.getManagerClass($table)() { 34 | return this.$strUtil.getManagerObjectName($table); 35 | } 36 | 37 | #end 38 | } -------------------------------------------------------------------------------- /sql2java-maven-plugin/src/main/resources/header.include.vm: -------------------------------------------------------------------------------- 1 | ##$Id: header.include.vm,v 1.5 2005/10/10 20:11:47 framiere Exp $ 2 | #set ( $db = $codewriter.db ) 3 | #set ( $schema = $db.getSchema() ) 4 | #set ( $tables = $db.getTables() ) 5 | #set ( $allPackages = $db.getAllPackages() ) 6 | #set ( $widgetPkg = "${pkg}.widget") 7 | #set ( $SPACE = " ") 8 | #set ( $IMPORT_BLOCK = "imports") 9 | #set ( $EXTENDS_BLOCK = "extends") 10 | #set ( $CLASS_BLOCK = "class") 11 | -------------------------------------------------------------------------------- /sql2java-maven-plugin/src/main/resources/manager.java.vm: -------------------------------------------------------------------------------- 1 | ##$Id: manager.java.vm,v 1.12 2005/10/17 09:09:59 framiere Exp $ 2 | #parse( "header.include.vm" ) 3 | #parse( "table.variables.include.vm" ) 4 | $codewriter.setCurrentJavaFilename("$table.getPackage()", "${managerClass}.java") 5 | package $table.getPackage(); 6 | 7 | import java.sql.Connection; 8 | import java.sql.PreparedStatement; 9 | import java.sql.ResultSet; 10 | import java.sql.SQLException; 11 | import java.sql.Statement; 12 | import java.sql.Types; 13 | import java.util.List; 14 | import javax.sql.DataSource; 15 | import org.slf4j.Logger; 16 | import org.slf4j.LoggerFactory; 17 | 18 | #foreach ($linkedPackage in $linkedPackages) 19 | import ${linkedPackage}.*; 20 | #end 21 | #if ($useLib) 22 | import $libPath.*; 23 | #end 24 | 25 | /** 26 | * Handles database calls (save, load, count, etc...) for the $tablename table. 27 | #if ( $codewriter.hasRemarks() ) 28 | * Remarks: $codewriter.getRemarks() 29 | #end 30 | */ 31 | public class $managerClass extends BaseManager<$beanClass> 32 | { 33 | private static final Logger log = LoggerFactory.getLogger(${managerClass}.class.getName()); 34 | 35 | #foreach ( $column in $columns ) #set ( $vcmo = $velocityCount - 1 ) 36 | /** 37 | * Identify the $column.getName() field. 38 | */ 39 | public static final int ID_$column.getConstName() = $vcmo; 40 | 41 | #end 42 | /** 43 | * Contains all the full fields of the $tablename table. 44 | */ 45 | private static final String[] FULL_FIELD_NAMES = 46 | { 47 | #foreach ( $column in $columns ) 48 | #if ( $velocityCount > 1 ),#end"$column.getFullName()" 49 | #end 50 | }; 51 | 52 | /** 53 | * Contains all the fields of the $tablename table. 54 | */ 55 | private static final String[] FIELD_NAMES = 56 | { 57 | #foreach ( $column in $columns ) 58 | #if ( $velocityCount > 1 ),#end"$column.getName()" 59 | #end 60 | }; 61 | 62 | /** 63 | * Field that contains the comma separated fields of the $tablename table. 64 | */ 65 | public static final String ALL_FULL_FIELDS = #foreach( $column in $columns ) 66 | #if ( $velocityCount > 1 ) 67 | 68 | + ",#else"#end$column.getFullName()"#end; 69 | 70 | /** 71 | * Field that contains the comma separated fields of the $tablename table. 72 | */ 73 | public static final String ALL_FIELDS = #foreach( $column in $columns ) 74 | #if ( $velocityCount > 1 ) 75 | 76 | + ",#else"#end$column.getName()"#end; 77 | 78 | /** 79 | * Contains all the full fields of the table. 80 | */ 81 | protected String[] getFullFieldNames() { return FULL_FIELD_NAMES; } 82 | 83 | /** 84 | * Contains all the fields of the table. 85 | */ 86 | protected String[] getFieldNames() { return FIELD_NAMES; } 87 | 88 | /** 89 | * Field that contains the comma separated fields of the table. 90 | */ 91 | protected String getAllFullFields() { return ALL_FULL_FIELDS; } 92 | 93 | /** 94 | * Field that contains the comma separated fields of the table. 95 | */ 96 | protected String getAllFields() { return ALL_FIELDS; } 97 | 98 | /** 99 | * Constructor 100 | */ 101 | public $managerClass(DataSource dataSource) 102 | { 103 | super(dataSource); 104 | } 105 | 106 | /** 107 | * Creates a new $beanClass instance. 108 | * 109 | * @return the new $beanClass 110 | */ 111 | public $beanClass create$beanClass() 112 | { 113 | return new $beanClass(); 114 | } 115 | 116 | /** 117 | * Creates a new $beanClass instance. 118 | * 119 | * @return the new $beanClass 120 | */ 121 | public $beanClass createBean() 122 | { 123 | return create$beanClass(); 124 | } 125 | 126 | /** 127 | * Table managed by this manager 128 | * 129 | * @return tablename 130 | */ 131 | public String getTableName() 132 | { 133 | return "$tablename"; 134 | } 135 | 136 | #if ( $primaryKeys.size() > 0 ) 137 | ////////////////////////////////////// 138 | // PRIMARY KEY METHODS 139 | ////////////////////////////////////// 140 | 141 | #set ( $keys = "" ) 142 | #foreach ( $pk in $primaryKeys ) 143 | #if ( $velocityCount > 1 )#set( $keys = "$keys, " )#end 144 | #set ( $keys = "$keys${pk.getJavaType()} $strUtil.getVarName($pk)" ) 145 | #end 146 | ##set ( $noWhereSelect = "SELECT \" + ALL_FIELDS + \" FROM \" + $tablename" ) 147 | ##set ( $baseSelect = "$noWhereSelect WHERE " ) 148 | #set ( $sql = "" ) 149 | #foreach( $pk in $primaryKeys ) 150 | #if ( $velocityCount > 1 )#set ( $sql = "$sql and " )#end 151 | #set ( $sql = "$sql$pk.getName()=?" ) 152 | #end 153 | /** 154 | * Loads a $beanClass from the $tablename using its key fields. 155 | * 156 | * @return a unique $beanClass 157 | */ 158 | //1 159 | public $beanClass loadByPrimaryKey($keys) throws SQLException { 160 | Connection c = null; 161 | PreparedStatement ps = null; 162 | try { 163 | c = getConnection(); 164 | StringBuilder sql = new StringBuilder("SELECT ").append(ALL_FIELDS).append(" FROM $tablename WHERE $sql"); 165 | if (log.isTraceEnabled()) log.trace("loadByPrimaryKey: {}", sql); 166 | ps = c.prepareStatement(sql.toString(), 167 | ResultSet.TYPE_SCROLL_INSENSITIVE, 168 | ResultSet.CONCUR_READ_ONLY); 169 | #foreach( $pk in $primaryKeys ) 170 | $pk.getPreparedStatementMethod($strUtil.getVarName($pk), $velocityCount) 171 | #end 172 | List<$beanClass> pReturn = loadByPreparedStatement(ps); 173 | if (pReturn.size() < 1) return null; 174 | else return pReturn.get(0); 175 | } finally { 176 | close(ps); 177 | releaseConnection(c); 178 | } 179 | } 180 | 181 | #set ( $sql = "" ) 182 | #foreach( $pk in $primaryKeys ) 183 | #if ( $velocityCount > 1 )#set ( $sql = "$sql and " )#end 184 | #set ( $sql = "$!sql$pk.getName()=?" ) 185 | #end 186 | /** 187 | * Deletes rows according to its keys. 188 | * 189 | * @return the number of deleted rows 190 | */ 191 | //2 192 | public int deleteByPrimaryKey($keys) throws SQLException { 193 | Connection c = null; 194 | PreparedStatement ps = null; 195 | try { 196 | c = getConnection(); 197 | StringBuilder sql = new StringBuilder("DELETE FROM $tablename WHERE $sql"); 198 | if (log.isTraceEnabled()) log.trace("loadByPrimaryKey: {}", sql); 199 | ps = c.prepareStatement(sql.toString(), 200 | ResultSet.TYPE_SCROLL_INSENSITIVE, 201 | ResultSet.CONCUR_READ_ONLY); 202 | #foreach( $pk in $primaryKeys ) 203 | $pk.getPreparedStatementMethod($strUtil.getVarName($pk), $velocityCount) 204 | #end 205 | return ps.executeUpdate(); 206 | } finally { 207 | close(ps); 208 | releaseConnection(c); 209 | } 210 | } 211 | #end 212 | ## ====================================================== 213 | ## xForeignKeys template 214 | ## ====================================================== 215 | #set ( $keysDone = [] ) 216 | #set ( $keysImported = [] ) 217 | #foreach ($impKey in $foreignKeys) 218 | #if ( $velocityCount == 1 ) 219 | 220 | ////////////////////////////////////// 221 | // GET/SET FOREIGN KEY BEAN METHOD 222 | ////////////////////////////////////// 223 | #end 224 | #set ( $importedtable = $impKey.getForeignColumn().getTableName() ) 225 | #set ( $importedClass = "${strUtil.getBeanClass($importedtable)}" ) 226 | #set ( $importedClassManager = "${strUtil.getManagerClass($importedtable)}" ) 227 | #if ( !$keysImported.contains( $importedClass ) ) 228 | #if ( $keysImported.add($importedClass) )#*squelch*##end 229 | /** 230 | * Retrieves the $importedClass object from the $tablename.$impKey.getName() field. 231 | * 232 | * @param bean the $beanClass 233 | * @return the associated $importedClass bean 234 | */ 235 | //3 GET IMPORTED 236 | public $importedClass[] get${importedClass}s($beanClass bean) throws SQLException { 237 | $importedClass other = ${importedClassManager}.getInstance().create${importedClass}(); 238 | other.${strUtil.getSetMethod($impKey.getForeignColumn())}(bean.${strUtil.getGetMethod($impKey)}()); 239 | return ${importedClassManager}.getInstance().loadUsingTemplate(other); 240 | } 241 | 242 | /** 243 | * Associates the $beanClass object to the $importedClass object. 244 | * 245 | * @param bean the $beanClass object to use 246 | * @param beanToSet the $importedClass object to associate to the $beanClass 247 | * @return the associated $importedClass bean 248 | */ 249 | //4 SET IMPORTED 250 | public $beanClass set${importedClass}($beanClass bean,$importedClass beanToSet) 251 | { 252 | bean.${strUtil.getSetMethod($impKey)}(beanToSet.${strUtil.getGetMethod($impKey.getForeignColumn())}()); 253 | return bean; 254 | } 255 | 256 | #end 257 | #end 258 | 259 | //_____________________________________________________________________ 260 | // 261 | // SAVE 262 | //_____________________________________________________________________ 263 | /** 264 | * Insert the $beanClass bean into the database. 265 | * 266 | * @param bean the $beanClass bean to be saved 267 | * @param orUpdate on duplicate key update 268 | * @param delayed use INSERT DELAYED and don't get generated keys 269 | */ 270 | //13 271 | public $beanClass insert($beanClass bean, boolean orUpdate, boolean delayed) throws SQLException { 272 | // mini checks 273 | if (!bean.isModified()) { 274 | return bean; // should not we log something ? 275 | } 276 | if (!bean.isNew()){ 277 | return update(bean); 278 | } 279 | Connection c = null; 280 | PreparedStatement ps = null; 281 | StringBuilder sql = null; 282 | try { 283 | c = getConnection(); 284 | ##-------------writePreInsert 285 | #set( $genKeyRetrieve = $codewriter.getProperty("generatedkey.retrieve", "") ) 286 | #set ( $hint = $codewriter.getProperty("generatedkey.statement").replaceAll("", $tablename) ) 287 | #if ( $primaryKeys.size() > 0 )#set ( $pKey = $primaryKeys.get(0) )#end 288 | #if ( $genKeyRetrieve == "before" && $primaryKeys.size() == 1 && $pKey.isColumnNumeric() ) 289 | if (!bean.$strUtil.getModifiedMethod($pKey)()) { 290 | StringBuilder hint = new StringBuilder("$hint"); 291 | if (log.isTraceEnabled()) log.trace("generatedKey : {}", hint); 292 | ps = c.prepareStatement(hint.toString()); 293 | ResultSet rs = null; 294 | try { 295 | rs = ps.executeQuery(); 296 | if(rs.next()) { 297 | bean.$strUtil.getSetMethod($pKey)($pKey.getResultSetMethodObject("1")); 298 | } else { 299 | if (delayed || orUpdate) log.trace("Could not retrieve generated key"); 300 | else log.warn("Could not retrieve generated key"); 301 | } 302 | } finally { 303 | close(ps, rs); 304 | ps=null; 305 | } 306 | } 307 | #end 308 | ##------------/writePreInsert 309 | int _dirtyCount = 0; 310 | #set ( $isPresentLock = $codewriter.isPresentLock( $columns ) ) 311 | #if ( $isPresentLock ) 312 | #set ($lockColumn = $codewriter.getLockColumn($columns)) 313 | bean.$strUtil.getSetMethod($lockColumn)(new $lockColumn.getJavaType()(String.valueOf(System.curentTimeMillis()))); 314 | 315 | #end 316 | sql = new StringBuilder(); 317 | if (delayed) sql.append("INSERT DELAYED into $tablename ("); 318 | else sql.append("INSERT into $tablename ("); 319 | 320 | #foreach( $column in $columns ) 321 | if (bean.$strUtil.getModifiedMethod($column)()) { 322 | if (_dirtyCount>0) { 323 | sql.append(","); 324 | } 325 | sql.append("$column.getName()"); 326 | _dirtyCount++; 327 | } 328 | 329 | #end 330 | sql.append(") values ("); 331 | if(_dirtyCount > 0) { 332 | sql.append("?"); 333 | for(int i = 1; i < _dirtyCount; i++) { 334 | sql.append(",?"); 335 | } 336 | } 337 | sql.append(")"); 338 | 339 | #if ( $genKeyRetrieve == "auto" ) 340 | #set( $prestArgs = "Statement.RETURN_GENERATED_KEYS" ) 341 | #else 342 | #set( $prestArgs = "ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY" ) 343 | #end 344 | 345 | if (orUpdate) { 346 | sql.append(" ON duplicate KEY UPDATE "); 347 | boolean useComma=false; 348 | #foreach( $column in $columns ) 349 | 350 | if (bean.$strUtil.getModifiedMethod($column)()) { 351 | if (useComma) { 352 | sql.append(","); 353 | } else { 354 | useComma=true; 355 | } 356 | sql.append("$column.getName()").append("=VALUES(").append("$column.getName()").append(")"); 357 | } 358 | #end 359 | 360 | } 361 | if (log.isTraceEnabled()) log.trace("insert : {}", sql); 362 | ps = c.prepareStatement(sql.toString(), 363 | $prestArgs); 364 | 365 | fillPreparedStatement(ps, bean, SEARCH_EXACT); 366 | 367 | ps.executeUpdate(); 368 | ##------------------writePostInsert 369 | #if ( $primaryKeys.size() == 1 ) 370 | #set($pKey = $primaryKeys.get(0)) 371 | #if ( $pKey.isColumnNumeric() ) 372 | #set ( $hint = $codewriter.getProperty("generatedkey.statement").replaceAll("
", $tablename) ) 373 | #if ( $genKeyRetrieve == "after" ) 374 | 375 | if (!bean.$strUtil.getModifiedMethod($pKey)()) { 376 | PreparedStatement ps2 = null; 377 | ResultSet rs = null; 378 | try { 379 | ps2 = c.prepareStatement("$hint"); 380 | rs = ps2.executeQuery(); 381 | if(rs.next()) { 382 | bean.$strUtil.getSetMethod($pKey)($pKey.getResultSetMethodObject("1")); 383 | } else { 384 | if (delayed || orUpdate) log.trace("Could not retrieve generated key"); 385 | else log.warn("Could not retrieve generated key"); 386 | } 387 | } finally { 388 | close(ps2, rs); 389 | } 390 | } 391 | #elseif ( $genKeyRetrieve == "auto" ) 392 | if (!bean.$strUtil.getModifiedMethod($pKey)() && !delayed) { 393 | ResultSet rs = ps.getGeneratedKeys(); 394 | try { 395 | if(rs.next()) { 396 | bean.$strUtil.getSetMethod($pKey)($pKey.getResultSetMethodObject("1")); 397 | } else { 398 | if (delayed || orUpdate) log.trace("Could not retrieve generated key"); 399 | else log.warn("Could not retrieve generated key"); 400 | } 401 | } finally { 402 | close(rs); 403 | } 404 | } 405 | #end 406 | #end 407 | #end 408 | ##-------------------/writePostInsert 409 | 410 | bean.isNew(false); 411 | bean.resetIsModified(); 412 | return bean; 413 | } finally { 414 | close(ps); 415 | releaseConnection(c); 416 | } 417 | } 418 | 419 | /** 420 | * Update the $beanClass bean record in the database according to the changes. 421 | * 422 | * @param bean the $beanClass bean to be updated 423 | */ 424 | //14 425 | public $beanClass update($beanClass bean) throws SQLException { 426 | // mini checks 427 | if (!bean.isModified()) { 428 | return bean; // should not we log something ? 429 | } 430 | if (bean.isNew()){ 431 | return save(bean); 432 | } 433 | Connection c = null; 434 | PreparedStatement ps = null; 435 | StringBuilder sql = null; 436 | try { 437 | c = getConnection(); 438 | 439 | #if ( $primaryKeys.size() == 0 ) 440 | $codewriter.log(" WARN : $tablename does not have any primary key...") 441 | #end 442 | #if ( $isPresentLock ) 443 | $lockColumn.getJavaType() oldLockValue = bean.$strUtil.getGetMethod($lockColumn)(); 444 | bean.$strUtil.getSetMethod($lockColumn))(new $lockColumn.getJavaType()(String.valueOf(System.currentTimeMillis()))); 445 | 446 | #end 447 | sql = new StringBuilder("UPDATE $tablename SET "); 448 | boolean useComma=false; 449 | #foreach( $column in $columns ) 450 | 451 | if (bean.$strUtil.getModifiedMethod($column)()) { 452 | if (useComma) { 453 | sql.append(","); 454 | } else { 455 | useComma=true; 456 | } 457 | sql.append("$column.getName()").append("=?"); 458 | } 459 | #end 460 | #if ( $primaryKeys.size() > 0 ) 461 | sql.append(" WHERE "); 462 | #end 463 | #set ($sql = "" ) 464 | #macro ( sqlAppend $somestr ) 465 | #set ( $sql = "$!sql$somestr" ) 466 | #end 467 | #foreach( $primaryKey in $primaryKeys ) 468 | #if ( $velocityCount > 1 )#sqlAppend( " AND " )#end 469 | #sqlAppend( "$primaryKey.getName()=?" ) 470 | #end 471 | #if ( $isPresentLock ) 472 | #if ( $primaryKeys.size() > 0 )#sqlAppend( " AND " )#end 473 | #sqlAppend( "$lockColumn.getName()=?") 474 | #end 475 | sql.append("$sql"); 476 | if (log.isTraceEnabled()) log.trace("update : {}", sql); 477 | ps = c.prepareStatement(sql.toString(), 478 | ResultSet.TYPE_SCROLL_INSENSITIVE, 479 | ResultSet.CONCUR_READ_ONLY); 480 | 481 | int _dirtyCount = fillPreparedStatement(ps, bean, SEARCH_EXACT); 482 | 483 | if (_dirtyCount == 0) { 484 | if (log.isTraceEnabled()) log.trace("The bean to look is not initialized... do not update."); 485 | return bean; 486 | } 487 | 488 | #foreach ( $pKey in $primaryKeys ) 489 | $pKey.getPreparedStatementMethod("bean.$strUtil.getGetMethod($pKey)()", "++_dirtyCount") 490 | #end 491 | #if ( $isPresentLock ) 492 | $lockColumn.getPreparedStatementMethod( "oldLockValue", "++_dirtyCount") 493 | if (ps.executeUpdate()==0) { 494 | throw new SQLException("sql2java.exception.optimisticlock"); 495 | } 496 | #else 497 | ps.executeUpdate(); 498 | #end 499 | bean.resetIsModified(); 500 | 501 | return bean; 502 | } finally { 503 | close(ps); 504 | releaseConnection(c); 505 | } 506 | } 507 | 508 | //_____________________________________________________________________ 509 | // 510 | // USING TEMPLATE 511 | //_____________________________________________________________________ 512 | 513 | /** 514 | * Deletes rows using a $beanClass template. 515 | * 516 | * @param bean the $beanClass object(s) to be deleted 517 | * @return the number of deleted objects 518 | */ 519 | //21 520 | public int deleteUsingTemplate($beanClass bean) throws SQLException { 521 | #if ( $primaryKeys.size() == 1) 522 | if (bean.$strUtil.getInitializedMethod($primaryKeys.get(0))()) 523 | return deleteByPrimaryKey(bean.$strUtil.getGetMethod($primaryKeys.get(0))()); 524 | 525 | #end 526 | Connection c = null; 527 | PreparedStatement ps = null; 528 | StringBuilder sql = new StringBuilder("DELETE FROM $tablename ");; 529 | StringBuilder sqlWhere = new StringBuilder(""); 530 | 531 | try { 532 | if (fillWhere(sqlWhere, bean, SEARCH_EXACT) == 0) { 533 | if (log.isTraceEnabled()) log.trace("The bean to look is not initialized... deleting all"); 534 | } else { 535 | sql.append(" WHERE ").append(sqlWhere); 536 | } 537 | if (log.isTraceEnabled()) log.trace("deleteUsingTemplate: {}", sql); 538 | 539 | c = getConnection(); 540 | ps = c.prepareStatement(sql.toString(), 541 | ResultSet.TYPE_SCROLL_INSENSITIVE, 542 | ResultSet.CONCUR_READ_ONLY); 543 | fillPreparedStatement(ps, bean, SEARCH_EXACT); 544 | 545 | int _rows = ps.executeUpdate(); 546 | return _rows; 547 | } finally { 548 | close(ps); 549 | releaseConnection(c); 550 | } 551 | } 552 | 553 | /** 554 | * fills the given stringbuilder with the sql where clausis constructed using the bean and the search type 555 | * @param sqlWhere the stringbuilder that will be filled 556 | * @param bean the bean to use for creating the where clausis 557 | * @param searchType exact ? like ? starting like ? 558 | * @return the number of clausis returned 559 | */ 560 | protected int fillWhere(StringBuilder sqlWhere, $beanClass bean, int searchType) throws SQLException { 561 | if (bean == null) 562 | return 0; 563 | int _dirtyCount = 0; 564 | StringBuilder sqlEqualsOperation = new StringBuilder("="); 565 | StringBuilder sqlOperation = new StringBuilder("="); 566 | if (searchType != SEARCH_EXACT) 567 | sqlOperation = new StringBuilder(" like "); 568 | #foreach( $column in $columns ) 569 | if (bean.$strUtil.getModifiedMethod($column)()) { 570 | _dirtyCount ++; 571 | #if ($column.isString()) 572 | sqlWhere.append((sqlWhere.length() == 0) ? " " : " AND ").append("$column.getName() ").append(sqlOperation).append("?"); 573 | #else 574 | sqlWhere.append((sqlWhere.length() == 0) ? " " : " AND ").append("$column.getName() ").append(sqlEqualsOperation).append("?"); 575 | #end 576 | } 577 | #end 578 | return _dirtyCount; 579 | } 580 | 581 | /** 582 | * fill the given prepared statement with the bean values and a search type 583 | * @param ps the preparedStatement that will be filled 584 | * @param bean the bean to use for creating the where clausis 585 | * @param searchType exact ? like ? starting like ? 586 | * @return the number of clausis returned 587 | */ 588 | protected int fillPreparedStatement(PreparedStatement ps, $beanClass bean, int searchType) throws SQLException { 589 | if (bean == null) 590 | return 0; 591 | int _dirtyCount = 0; 592 | #foreach ( $column in $columns ) 593 | if (bean.$strUtil.getModifiedMethod($column)()) { 594 | #if ($column.isString()) 595 | switch (searchType){ 596 | case SEARCH_EXACT: 597 | if (log.isTraceEnabled()) log.trace("Setting for {} [{}]", _dirtyCount, bean.$strUtil.getGetMethod($column)()); 598 | $column.getPreparedStatementMethod("bean.$strUtil.getGetMethod($column)()", "++_dirtyCount"); 599 | break; 600 | case SEARCH_LIKE: 601 | if (log.isTraceEnabled()) log.trace("Setting for {} [%{}%]", _dirtyCount, bean.$strUtil.getGetMethod($column)()); 602 | $column.getPreparedStatementMethod("${Q}%${Q} + bean.$strUtil.getGetMethod($column)() + ${Q}%${Q}", "++_dirtyCount"); 603 | break; 604 | case SEARCH_STARTING_LIKE: 605 | if (log.isTraceEnabled()) log.trace("Setting for {} [{}%]", _dirtyCount, bean.$strUtil.getGetMethod($column)()); 606 | $column.getPreparedStatementMethod("${Q}%${Q} + bean.$strUtil.getGetMethod($column)()", "++_dirtyCount"); 607 | break; 608 | case SEARCH_ENDING_LIKE: 609 | if (log.isTraceEnabled()) log.trace("Setting for {} [%{}]", _dirtyCount, bean.$strUtil.getGetMethod($column)()); 610 | $column.getPreparedStatementMethod("bean.$strUtil.getGetMethod($column)() + ${Q}%${Q}", "++_dirtyCount"); 611 | break; 612 | } 613 | #else 614 | if (log.isTraceEnabled()) log.trace("Setting for {} [{}]", _dirtyCount, bean.$strUtil.getGetMethod($column)()); 615 | $column.getPreparedStatementMethod("bean.$strUtil.getGetMethod($column)()", "++_dirtyCount"); 616 | #end 617 | } 618 | #end 619 | return _dirtyCount; 620 | } 621 | 622 | /** 623 | * Transforms a ResultSet iterating on the $tablename on a $beanClass bean. 624 | * 625 | * @param rs the ResultSet to be transformed 626 | * @return bean resulting $beanClass bean 627 | */ 628 | public $beanClass decodeRow(ResultSet rs) throws SQLException { 629 | $beanClass bean = create$beanClass(); 630 | ## the set statement casts $velocityCount to a string 631 | #foreach ( $column in $columns ) 632 | #set ($vCount = "$velocityCount" ) 633 | bean.$strUtil.getSetMethod($column)($column.getResultSetMethodObject($vCount)); 634 | #end 635 | bean.isNew(false); 636 | bean.resetIsModified(); 637 | return bean; 638 | } 639 | 640 | /** 641 | * Transforms a ResultSet iterating on the $tablename on a $beanClass bean using the names of the columns 642 | * 643 | * @param rs the ResultSet to be transformed 644 | * @return bean resulting $beanClass bean 645 | */ 646 | public $beanClass metaDataDecodeRow(ResultSet rs) throws SQLException { 647 | $beanClass bean = create$beanClass(); 648 | #foreach ( $column in $columns ) 649 | bean.$strUtil.getSetMethod($column)($column.getResultSetMethodObject("${Q}$column.getName()${Q}")); 650 | #end 651 | bean.isNew(false); 652 | bean.resetIsModified(); 653 | return bean; 654 | } 655 | 656 | } 657 | -------------------------------------------------------------------------------- /sql2java-maven-plugin/src/main/resources/table.variables.include.vm: -------------------------------------------------------------------------------- 1 | ##$Id: table.variables.include.vm,v 1.7 2005/10/10 22:06:26 framiere Exp $ 2 | #set ( $tablename = $codewriter.tableName() ) 3 | #set ( $tableName = $strUtil.convertName($codewriter.tableName()) ) 4 | #set ( $columns = $codewriter.getColumns() ) 5 | #set ( $foreignKeys = $codewriter.getForeignKeys() ) 6 | #set ( $importedKeys = $codewriter.getImportedKeys() ) 7 | #set ( $primaryKeys = $codewriter.getPrimaryKeys() ) 8 | #set ( $coreClass = $strUtil.getCoreClass($table) ) 9 | #set ( $managerClass = $strUtil.getManagerClass($table) ) 10 | #set ( $beanClass = $strUtil.getBeanClass($table) ) 11 | #set ( $factoryClass = $strUtil.getFactoryClass($table) ) 12 | #set ( $httpFactoryClass = $strUtil.getHttpFactoryClass($table) ) 13 | #set ( $comparatorClass = $strUtil.getComparatorClass($table) ) 14 | #set ( $listenerClass = $strUtil.getListenerClass($table) ) 15 | #set ( $rendererClass = $strUtil.getRendererClass($table) ) 16 | #set ( $widgetFactoryClass = $strUtil.getWidgetFactoryClass($table) ) 17 | #set ( $widgetClass = $strUtil.getWidgetClass($table) ) 18 | #set ( $linkedTables = $table.getLinkedTables()) 19 | #set ( $linkedPackages = $table.getLinkedPackages()) 20 | #set ( $pkgPath = $table.getPackagePath()) 21 | #set ( $Q = '"' ) 22 | -------------------------------------------------------------------------------- /sql2java-maven-plugin/src/test/config/test.properties: -------------------------------------------------------------------------------- 1 | # 2 | # SAMPLE PROPERTIES FILE FOR SQL2JAVA 3 | # 4 | 5 | 6 | #---------------------------------------------- 7 | # (1/7) CONFIGURE YOUR DATABASE ACCESS 8 | #---------------------------------------------- 9 | #jdbc.driver=org.hsqldb.jdbcDriver 10 | #jdbc.url=jdbc:hsqldb:hsql://localhost 11 | #jdbc.username=sa 12 | #jdbc.password= 13 | #jdbc.schema= 14 | 15 | jdbc.driver=com.mysql.jdbc.Driver 16 | jdbc.url=jdbc:mysql://localhost:3306/schema_here 17 | jdbc.username= 18 | jdbc.password= 19 | jdbc.schema=schema_here 20 | 21 | 22 | #------------------------------------------------- 23 | # (2/7) CONFIGURE RETRIEVAL OF AUTO GENERATED KEY 24 | #------------------------------------------------- 25 | # For those who do not want to read below, please simply pick up the 26 | # configuration associated with your database. 27 | # 28 | # More explanation: 29 | # When you save a bean whose primary key is numeric and has no value set, 30 | # we assume that you want sql2java to retrieve a key's value generated 31 | # on the database side. 32 | # 33 | # generatedkey.retrieve can take 4 values: 34 | # 35 | # auto - the standard approach when you have a JDBC 3.0 driver. 36 | # 37 | # before - the key's value is retrieved before inserting the record. 38 | # 39 | # after - the key's value is retrieved after inserting the record 40 | # 41 | # none - the key's value is never retrieved, frankly I doubt you 42 | # want this configuration 43 | # 44 | # If you set it to before or after you also need to configure the 45 | # autogeneratedkey.statement properties. 46 | #
is replaced at code generation time by the table name. 47 | # You may adjust this properties to fit your own naming convention. 48 | # 49 | # PICK THE CONFIGURATION ASSOCIATED WITH YOUR DATABASE 50 | # (or create one, but in that case let us know so we can add it here... :-) 51 | # 52 | #-- HSQL ------ 53 | #generatedkey.retrieve=after 54 | #generatedkey.statement=CALL IDENTITY() 55 | # 56 | #-- IF YOU USE A JDBC 3.0 DRIVER (works with mysql, ORACLE 9, etc..) ------ 57 | generatedkey.retrieve=auto 58 | generatedkey.statement= 59 | # 60 | #-- MYSQL (without jdbc 3.0 driver) ------ 61 | #generatedkey.retrieve=after 62 | #generatedkey.statement=SELECT last_insert_id() 63 | # 64 | #-- POSTGRESQL ------ 65 | #generatedkey.retrieve=before 66 | #generatedkey.statement=SELECT nextval('
_SEQ') 67 | # 68 | 69 | 70 | #---------------------------------------------- 71 | # (3/7) GENERATED SOURCE CODE 72 | #---------------------------------------------- 73 | 74 | # Package name for the generated source code 75 | mgrwriter.package=net.sql2java.sample.database 76 | 77 | # Destination of the generated source code (package hierarchy is preserved) 78 | mgrwriter.destdir=target/generated-sources 79 | 80 | # Property file to use when initializing Velocity 81 | #mgrwriter.velocityprops=somefile 82 | 83 | # templates (you can generate java files, jsp, etc...) 84 | 85 | mgrwriter.templates.loadingpath= 86 | 87 | mgrwriter.templates.perschema= daobean.java.vm, \ 88 | daomanager.java.vm, \ 89 | basemanager.java.vm, \ 90 | database.java.vm 91 | 92 | mgrwriter.templates.pertable= bean.java.vm, \ 93 | manager.java.vm 94 | 95 | # sets a prefix to prepend to all generated classes 96 | # useful if you are worried about namespace collision with reserved words 97 | # or java.lang classes 98 | #mgrwriter.classprefix= 99 | 100 | 101 | #----------------------------------------------- 102 | # (4/7) JDBC TYPES Mapping 103 | #----------------------------------------------- 104 | # 105 | # jdbc DATE mapping can be: 106 | # java.sql.Date 107 | # java.util.Date 108 | jdbc2java.date=java.util.Date 109 | 110 | # jdbc TIME mapping can be: 111 | # java.sql.Time 112 | # java.util.Date 113 | jdbc2java.time=java.util.Date 114 | 115 | # jdbc TIMESTAMP mappning can be: 116 | # java.sql.Timestamp 117 | # java.util.Date 118 | jdbc2java.timestamp=java.util.Date 119 | 120 | 121 | #----------------------------------------------- 122 | # (5/7) FILTER OUT CERTAIN TABLES 123 | #----------------------------------------------- 124 | # 125 | # COMMA SEPARATED list of table types to be mapped 126 | # Commonly seen types are TABLE, VIEW, SYSTEM TABLE, SYNONYM 127 | jdbc.tabletypes=TABLE 128 | 129 | # Table name pattern of tables to be mapped to classes. 130 | # available wildcard: % 131 | # defaults to % 132 | # You can specify several patterns separated by commas. 133 | jdbc.tablenamepattern=% 134 | 135 | # SPACE SEPARATED list of tables to include or exclude. If you specify both, 136 | # the include list will take priority. If these fields are left commented out, 137 | # all tables in the specified schema will get mapped to classes 138 | #mgrwriter.include=Testing 139 | #mgrwriter.exclude= 140 | 141 | 142 | #----------------------------------------------- 143 | # (6/7) CONFIGURE OPTIMISTIC LOCK 144 | #----------------------------------------------- 145 | # optimisticlock.type can take 2 values: 146 | # none - the optimistic lock mechanism is disabled (default). 147 | # timestamp - the optimistic lock column contains the System.currentTimeMillis() value. 148 | # 149 | # optimisticlock.column takes the column name used by optimistic lock mechanism in your database. 150 | # If this column is not present in some table the optimistic lock is not applied there. 151 | # the column mapping can be java.lang.Long or java.lang.String. 152 | # (jdbc type size >= 13 characters) 153 | optimisticlock.type=timestamp 154 | optimisticlock.column=version_time 155 | 156 | 157 | #----------------------------------------------- 158 | # (7/7) ORGANISE YOUR SUBPACKAGES 159 | #----------------------------------------------- 160 | #subpackage.1.name=products.delivery 161 | #subpackage.1.tables=delivery 162 | 163 | #subpackage.2.name=products.product 164 | #subpackage.2.tables=product 165 | 166 | #subpackage.3.name=products.manufacturer 167 | #subpackage.3.tables=manufacturer 168 | 169 | #subpackage.4.name=users 170 | #subpackage.4.tables=customer, shipper, 171 | 172 | 173 | -------------------------------------------------------------------------------- /sql2java-test/README: -------------------------------------------------------------------------------- 1 | # Test of sqlfile and sql2java plugins 2 | 3 | Use this as a model for how to use the plugin in your environment. E.g. 4 | - Put your SQL in src/main/sql/NN-blah.sql 5 | - Use sqlfile plugin in build->plugins to source it into a temporary hsqldb 6 | - Use sql2java plugin in build->plugins to generate managers and beans to generated source dir 7 | - Test, etc. 8 | 9 | Currently known problem: 10 | 11 | [WARNING] Some problems were encountered while building the effective model for net.sourceforge:sql2java-test:jar:1.0-SNAPSHOT 12 | [WARNING] 'build.plugins.plugin.(groupId:artifactId)' must be unique but found duplicate declaration of plugin net.sourceforge:sql2java-maven-plugin @ net.sourceforge:sql2java-test:[unknown-version], /Users/xgp/projects/sql2java/github/sql2java-test/pom.xml, line 74, column 15 13 | [WARNING] 14 | [WARNING] It is highly recommended to fix these problems because they threaten the stability of your build. 15 | [WARNING] 16 | [WARNING] For this reason, future Maven versions might no longer support building such malformed projects. 17 | 18 | This is because, for some reason, my plugin mojos aren't picking up all the properties when they are specified in separate s of the same plugin. Will fix later. 19 | -------------------------------------------------------------------------------- /sql2java-test/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 4.0.0 5 | com.github.xgp 6 | sql2java-test 7 | jar 8 | sql2java-test 9 | 10 | 11 | com.github.xgp 12 | sql2java 13 | 0.9.1-SNAPSHOT 14 | 15 | 16 | 17 | 18 | org.slf4j 19 | slf4j-api 20 | 21 | 22 | com.github.xgp 23 | sql2java-lib 24 | ${project.parent.version} 25 | 26 | 27 | org.slf4j 28 | slf4j-simple 29 | test 30 | 31 | 32 | org.hsqldb 33 | hsqldb 34 | test 35 | 36 | 37 | org.hsqldb 38 | sqltool 39 | test 40 | 41 | 42 | junit 43 | junit 44 | test 45 | 46 | 47 | 48 | 49 | 50 | 51 | com.github.xgp 52 | sql2java-maven-plugin 53 | ${project.parent.version} 54 | 55 | 56 | sqlfile 57 | initialize 58 | 59 | sqlfile 60 | 61 | 62 | 63 | 64 | true 65 | ${project.basedir}/src/main/sql 66 | org.hsqldb.jdbc.JDBCDriver 67 | jdbc:hsqldb:file:${project.build.directory}/databases/test 68 | SA 69 | 70 | PUBLIC 71 | 72 | 73 | 74 | org.hsqldb 75 | hsqldb 76 | ${hsqldb.version} 77 | 78 | 79 | 80 | 81 | com.github.xgp 82 | sql2java-maven-plugin 83 | ${project.parent.version} 84 | 85 | 86 | sql2java 87 | generate-sources 88 | 89 | sql2java 90 | 91 | 92 | 93 | 94 | ${project.build.directory}/generated-sources/sql2java 95 | ${project.basedir}/src/main/resources/sql2java.properties 96 | org.hsqldb.jdbc.JDBCDriver 97 | jdbc:hsqldb:file:${project.build.directory}/databases/test 98 | SA 99 | 100 | PUBLIC 101 | com.test 102 | 103 | 104 | 105 | org.hsqldb 106 | hsqldb 107 | ${hsqldb.version} 108 | 109 | 110 | 111 | 112 | org.codehaus.mojo 113 | build-helper-maven-plugin 114 | 1.12 115 | 116 | 117 | add-source 118 | generate-sources 119 | 120 | add-source 121 | 122 | 123 | 124 | ${project.build.directory}/generated-sources/sql2java 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | -------------------------------------------------------------------------------- /sql2java-test/src/main/resources/sql2java.properties: -------------------------------------------------------------------------------- 1 | # 2 | # PROPERTIES FILE FOR SQL2JAVA 3 | # 4 | 5 | 6 | #------------------------------------------------- 7 | # (2/6) CONFIGURE RETRIEVAL OF AUTO GENERATED KEY 8 | #------------------------------------------------- 9 | # For those who do not want to read below, please simply pick up the 10 | # configuration associated with your database. 11 | # 12 | # More explanation: 13 | # When you save a bean whose primary key is numeric and has no value set, 14 | # we assume that you want sql2java to retrieve a key's value generated 15 | # on the database side. 16 | # 17 | # generatedkey.retrieve can take 4 values: 18 | # 19 | # auto - the standard approach when you have a JDBC 3.0 driver. 20 | # 21 | # before - the key's value is retrieved before inserting the record. 22 | # 23 | # after - the key's value is retrieved after inserting the record 24 | # 25 | # none - the key's value is never retrieved, frankly I doubt you 26 | # want this configuration 27 | # 28 | # If you set it to before or after you also need to configure the 29 | # autogeneratedkey.statement properties. 30 | #
is replaced at code generation time by the table name. 31 | # You may adjust this properties to fit your own naming convention. 32 | # 33 | # PICK THE CONFIGURATION ASSOCIATED WITH YOUR DATABASE 34 | # (or create one, but in that case let us know so we can add it here... :-) 35 | # 36 | #-- HSQL ------ 37 | #generatedkey.retrieve=after 38 | #generatedkey.statement=CALL IDENTITY() 39 | 40 | #-- IF YOU USE A JDBC 3.0 DRIVER (works with mysql, ORACLE 9, etc..) ------ 41 | generatedkey.retrieve=auto 42 | generatedkey.statement= 43 | 44 | #---------------------------------------------- 45 | # (3/6) GENERATED SOURCE CODE 46 | #---------------------------------------------- 47 | 48 | # Package name for the generated source code 49 | mgrwriter.package=com.test 50 | 51 | # Property file to use when initializing Velocity 52 | #mgrwriter.velocityprops=somefile 53 | 54 | # templates (you can generate java files, jsp, etc...) 55 | 56 | mgrwriter.templates.loadingpath=templates/velocity/global, \ 57 | templates/velocity/table, \ 58 | templates/velocity/includes 59 | 60 | mgrwriter.templates.perschema= database.java.vm 61 | 62 | mgrwriter.templates.pertable= bean.java.vm, \ 63 | manager.java.vm 64 | 65 | #----------------------------------------------- 66 | # (4/6) JDBC TYPES Mapping 67 | #----------------------------------------------- 68 | # 69 | # jdbc DATE mapping can be: 70 | # java.sql.Date 71 | # java.util.Date 72 | jdbc2java.date=java.util.Date 73 | 74 | # jdbc TIME mapping can be: 75 | # java.sql.Time 76 | # java.util.Date 77 | jdbc2java.time=java.util.Date 78 | 79 | # jdbc TIMESTAMP mappning can be: 80 | # java.sql.Timestamp 81 | # java.util.Date 82 | jdbc2java.timestamp=java.util.Date 83 | 84 | #----------------------------------------------- 85 | # (5/6) FILTER OUT CERTAIN TABLES 86 | #----------------------------------------------- 87 | # 88 | # COMMA SEPARATED list of table types to be mapped 89 | # Commonly seen types are TABLE, VIEW, SYSTEM TABLE, SYNONYM 90 | jdbc.tabletypes=TABLE 91 | 92 | # Table name pattern of tables to be mapped to classes. 93 | # available wildcard: % 94 | # defaults to % 95 | # You can specify several patterns separated by commas. 96 | jdbc.tablenamepattern=% 97 | 98 | # SPACE SEPARATED list of tables to include or exclude. If you specify both, 99 | # the include list will take priority. If these fields are left commented out, 100 | # all tables in the specified schema will get mapped to classes 101 | #mgrwriter.include=Testing 102 | #mgrwriter.exclude= 103 | 104 | #----------------------------------------------- 105 | # (6/6) CONFIGURE OPTIMISTIC LOCK 106 | #----------------------------------------------- 107 | # optimisticlock.type can take 2 values: 108 | # none - the optimistic lock mechanism is disabled (default). 109 | # timestamp - the optimistic lock column contains the System.currentTimeMillis() value. 110 | # 111 | # optimisticlock.column takes the column name used by optimistic lock mechanism in your database. 112 | # If this column is not present in some table the optimistic lock is not applied there. 113 | # the column mapping can be java.lang.Long or java.lang.String. 114 | # (jdbc type size >= 13 characters) 115 | optimisticlock.type=timestamp 116 | optimisticlock.column=version_time 117 | -------------------------------------------------------------------------------- /sql2java-test/src/main/resources/sqltool.rc: -------------------------------------------------------------------------------- 1 | urlid test 2 | url jdbc:hsqldb:file:target/databases/test 3 | username SA 4 | password 5 | -------------------------------------------------------------------------------- /sql2java-test/src/main/sql/00-test.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE person ( 2 | id integer GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, 3 | username varchar(255) NOT NULL, 4 | first_name varchar(255) NOT NULL, 5 | last_name varchar(255) NOT NULL, 6 | create_date datetime NOT NULL, 7 | update_date timestamp DEFAULT CURRENT_TIMESTAMP NOT NULL, 8 | UNIQUE (username) 9 | ); 10 | 11 | CREATE TABLE phone ( 12 | id integer GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, 13 | phone_number varchar(30) NOT NULL, 14 | phone_type integer NOT NULL, 15 | person_id integer NOT NULL, 16 | create_date datetime NOT NULL, 17 | FOREIGN KEY (person_id) REFERENCES person(id), 18 | UNIQUE (phone_number) 19 | ); 20 | -------------------------------------------------------------------------------- /sql2java-test/src/main/sql/01-test.sql: -------------------------------------------------------------------------------- 1 | insert into person (username, first_name, last_name, create_date) values ('farkhan', 'Farkhan', 'Parambulator', now()); 2 | insert into phone (phone_number, phone_type, person_id, create_date) values ('+12125551212', 1, identity(), now()); 3 | -------------------------------------------------------------------------------- /sql2java-test/src/test/java/com/test/TransactionTest.java: -------------------------------------------------------------------------------- 1 | package com.test; 2 | 3 | import java.io.File; 4 | import java.util.Date; 5 | import javax.sql.DataSource; 6 | import net.sourceforge.sql2java.lib.*; 7 | import org.hsqldb.jdbc.JDBCDataSource; 8 | import org.junit.*; 9 | 10 | public class TransactionTest { 11 | 12 | @Test public void twoTableCommitTransactionTest() throws Exception { 13 | JDBCDataSource ds = new JDBCDataSource(); 14 | ds.setDatabase("jdbc:hsqldb:file:target/databases/test"); 15 | ds.setUser("SA"); 16 | ds.setPassword(""); 17 | 18 | PublicDatabase db = new PublicDatabase(ds); 19 | //clean up 20 | db.deleteByWhere(Phone.class, "WHERE PHONE_NUMBER='+14105551212'"); 21 | db.deleteByWhere(Person.class, "WHERE USERNAME='hansolo'"); 22 | 23 | try { 24 | db.beginTransaction(Txn.Isolation.REPEATABLE_READ); 25 | Person s0 = db.createBean(Person.class); 26 | s0.setUsername("hansolo"); 27 | s0.setFirstName("Harrison"); 28 | s0.setLastName("Ford"); 29 | s0.setCreateDate(new Date()); 30 | s0 = db.save(s0); 31 | Phone m0 = db.createBean(Phone.class); 32 | m0.setPersonId(s0.getId()); 33 | m0.setPhoneType(1); 34 | m0.setPhoneNumber("+14105551212"); 35 | m0.setCreateDate(new Date()); 36 | m0 = db.save(m0); 37 | db.commitTransaction(); 38 | } finally { 39 | db.endTransaction(); 40 | } 41 | 42 | Person s1 = db.loadUniqueByWhere(Person.class, "WHERE USERNAME='hansolo'"); 43 | Assert.assertNotNull(s1); 44 | 45 | Phone m1 = db.loadUniqueByWhere(Phone.class, "WHERE PHONE_NUMBER='+14105551212'"); 46 | Assert.assertNotNull(m1); 47 | } 48 | 49 | 50 | @Test public void twoTableRollbackTransactionTest() throws Exception { 51 | JDBCDataSource ds = new JDBCDataSource(); 52 | ds.setDatabase("jdbc:hsqldb:file:target/databases/test"); 53 | ds.setUser("SA"); 54 | ds.setPassword(""); 55 | 56 | PublicDatabase db = new PublicDatabase(ds); 57 | //clean up 58 | db.deleteByWhere(Phone.class, "WHERE PHONE_NUMBER='+14105551212'"); 59 | db.deleteByWhere(Person.class, "WHERE USERNAME='hansolo'"); 60 | 61 | try { 62 | db.beginTransaction(Txn.Isolation.REPEATABLE_READ); 63 | Person s0 = db.createBean(Person.class); 64 | s0.setUsername("hansolo"); 65 | s0.setFirstName("Harrison"); 66 | s0.setLastName("Ford"); 67 | s0.setCreateDate(new Date()); 68 | s0 = db.save(s0); 69 | Phone m0 = db.createBean(Phone.class); 70 | m0.setPersonId(s0.getId()); 71 | m0.setPhoneType(1); 72 | m0.setPhoneNumber("+14105551212"); 73 | m0.setCreateDate(new Date()); 74 | m0 = db.save(m0); 75 | db.rollbackTransaction(); 76 | } finally { 77 | db.endTransaction(); 78 | } 79 | 80 | Person s1 = db.loadUniqueByWhere(Person.class, "WHERE USERNAME='hansolo'"); 81 | Assert.assertNull(s1); 82 | 83 | Phone m1 = db.loadUniqueByWhere(Phone.class, "WHERE PHONE_NUMBER='+14105551212'"); 84 | Assert.assertNull(m1); 85 | } 86 | 87 | } 88 | -------------------------------------------------------------------------------- /sql2java-test/src/test/resources/sqltool.rc: -------------------------------------------------------------------------------- 1 | urlid test 2 | url jdbc:hsqldb:file:target/databases/test 3 | username SA 4 | password 5 | --------------------------------------------------------------------------------