Return-Path: Delivered-To: apmail-jakarta-commons-dev-archive@apache.org Received: (qmail 79168 invoked from network); 9 Sep 2002 13:48:23 -0000 Received: from unknown (HELO nagoya.betaversion.org) (192.18.49.131) by daedalus.apache.org with SMTP; 9 Sep 2002 13:48:23 -0000 Received: (qmail 14161 invoked by uid 97); 9 Sep 2002 13:48:38 -0000 Delivered-To: qmlist-jakarta-archive-commons-dev@jakarta.apache.org Received: (qmail 14119 invoked by uid 97); 9 Sep 2002 13:48:37 -0000 Mailing-List: contact commons-dev-help@jakarta.apache.org; run by ezmlm Precedence: bulk List-Unsubscribe: List-Subscribe: List-Help: List-Post: List-Id: "Jakarta Commons Developers List" Reply-To: "Jakarta Commons Developers List" Delivered-To: mailing list commons-dev@jakarta.apache.org Received: (qmail 14108 invoked by uid 97); 9 Sep 2002 13:48:36 -0000 X-Antivirus: nagoya (v4218 created Aug 14 2002) Date: 9 Sep 2002 13:47:57 -0000 Message-ID: <20020909134757.59604.qmail@icarus.apache.org> From: jstrachan@apache.org To: jakarta-commons-sandbox-cvs@apache.org Subject: cvs commit: jakarta-commons-sandbox/sql/src/test/org/apache/commons/sql TestDataModelRoundTrip.java X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N jstrachan 2002/09/09 06:47:57 Modified: sql/src/jelly createSql.jelly defineTags.jelly Added: sql/src/java/org/apache/commons/sql/model Reference.java ForeignKey.java Column.java Table.java Database.java sql/src/java/org/apache/commons/sql/task DataDumpTask.java JDBCTransformTask.java DocumentationTask.java TypeMap.java DataModelTask.java DataSQLTask.java DataDTDTask.java SQLTask.java SQLExec.java CreateDatabase.java sql/src/test/org/apache/commons/sql TestDataModelRoundTrip.java Removed: sql/src/java/org/apache/commons/sql DataSQLTask.java DataDTDTask.java SQLTask.java SQLExec.java CreateDatabase.java DataDumpTask.java JDBCTransformTask.java DocumentationTask.java TypeMap.java DataModelTask.java sql/src/test/org/apache/commons/sql/datamodel TestDataModelRoundTrip.java sql/src/java/org/apache/commons/sql/datamodel Column.java Database.java Reference.java Table.java ForeignKey.java Log: refactored the packages a little bit. sql.model contains the bean model sql.task contains the Ant Tasks we could put some helper classes at sql.* Revision Changes Path 1.1 jakarta-commons-sandbox/sql/src/java/org/apache/commons/sql/model/Reference.java Index: Reference.java =================================================================== package org.apache.commons.sql.model; public class Reference { private String local; private String foreign; public Reference() {} public String getLocal() { return local; } public void setLocal(String local) { this.local = local; } public String getForeign() { return foreign; } public void setForeign(String foreign) { this.foreign = foreign; } } 1.1 jakarta-commons-sandbox/sql/src/java/org/apache/commons/sql/model/ForeignKey.java Index: ForeignKey.java =================================================================== package org.apache.commons.sql.model; import java.util.Iterator; import java.util.ArrayList; import java.util.List; public class ForeignKey { private String foreignTable; private List references = new ArrayList(); public ForeignKey() {} public String getForeignTable() { return foreignTable; } public void setForeignTable(String foreignTable) { this.foreignTable= foreignTable; } public void addReference(Reference reference) { references.add(reference); } public List getReferences() { return references; } } 1.1 jakarta-commons-sandbox/sql/src/java/org/apache/commons/sql/model/Column.java Index: Column.java =================================================================== package org.apache.commons.sql.model; import java.util.Iterator; import java.util.ArrayList; import java.util.List; public class Column { private String name; private boolean primaryKey = false; private boolean required = false; private String type; private int size = 0; public Column () {} public String getName() { return name; } public void setName(String name) { this.name = name; } public boolean isPrimaryKey() { return primaryKey; } public void setPrimaryKey(boolean primaryKey) { this.primaryKey = primaryKey; } public boolean isRequired() { return required; } public void setRequired(boolean required) { this.required = required; } public String getType() { return type; } public void setType(String type) { this.type = type; } public int getSize() { return size; } public void setSize(int size) { this.size=size; } } 1.1 jakarta-commons-sandbox/sql/src/java/org/apache/commons/sql/model/Table.java Index: Table.java =================================================================== package org.apache.commons.sql.model; import java.util.Iterator; import java.util.ArrayList; import java.util.List; public class Table { private String name; private List columns = new ArrayList(); private List foreignKeys = new ArrayList(); public Table() { } public String getName() { return name; } public void setName(String name) { this.name=name; } public void addColumn(Column column) { columns.add(column); } public List getColumns() { return columns; } public void addForeignKey(ForeignKey foreignKey) { foreignKeys.add(foreignKey); } public List getForeignKeys() { return foreignKeys; } public Column getColumn(int index) { return (Column) columns.get(index); } public ForeignKey getForeignKey(int index) { return (ForeignKey) foreignKeys.get(index); } // Helper methods /** * @return true if there is at least one primary key column * on this table */ public boolean hasPrimaryKey() { for (Iterator iter = getColumns().iterator(); iter.hasNext(); ) { Column column = (Column) iter.next(); if ( column.isPrimaryKey() ) { return true; } } return false; } } 1.1 jakarta-commons-sandbox/sql/src/java/org/apache/commons/sql/model/Database.java Index: Database.java =================================================================== package org.apache.commons.sql.model; import java.util.Iterator; import java.util.ArrayList; import java.util.List; public class Database { private String name; private String idMethod; private List tables = new ArrayList(); public Database() { } public String getName() { return name; } public void setName(String name) { this.name=name; } public void setIdMethod(String idMethod) { this.idMethod=idMethod; } public void addTable(Table table) { tables.add(table); } public List getTables() { return tables; } // Additions for PropertyUtils public void setTable(int index, Table table) { addTable(table); } public Table getTable(int index) { return (Table) tables.get(index); } public String toString() { return super.toString() + "[name=" + name + ";tableCount=" + tables.size() + "]"; } } 1.1 jakarta-commons-sandbox/sql/src/java/org/apache/commons/sql/task/DataDumpTask.java Index: DataDumpTask.java =================================================================== package org.apache.commons.sql.task; /* ==================================================================== * The Apache Software License, Version 1.1 * * Copyright (c) 2001 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Apache" and "Apache Software Foundation" and * "Apache Turbine" must not be used to endorse or promote products * derived from this software without prior written permission. For * written permission, please contact apache@apache.org. * * 5. Products derived from this software may not be called "Apache", * "Apache Turbine", nor may "Apache" appear in their name, without * prior written permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . */ import java.util.Iterator; import java.util.NoSuchElementException; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Statement; import org.apache.tools.ant.Project; import org.apache.velocity.context.Context; import com.workingdogs.village.QueryDataSet; import com.workingdogs.village.Record; /** * An extended Texen task used for dumping data from db into XML * * @author Fedor Karpelevitch * @author Jason van Zyl * @author Daniel Rall * @version $Id: TorqueDataDumpTask.java,v 1.7 2002/04/11 22:02:06 mpoeschl Exp $ */ public class DataDumpTask extends DataModelTask { /** * Database name. */ private String databaseName; /** * Database URL used for JDBC connection. */ private String databaseUrl; /** * Database driver used for JDBC connection. */ private String databaseDriver; /** * Database user used for JDBC connection. */ private String databaseUser; /** * Database password used for JDBC connection. */ private String databasePassword; /** * The database connection used to retrieve the data to dump. */ private Connection conn; /** * The statement used to acquire the data to dump. */ private Statement stmt; /** * Get the database name to dump * * @return The DatabaseName value */ public String getDatabaseName() { return databaseName; } /** * Set the database name * * @param v The new DatabaseName value */ public void setDatabaseName(String v) { databaseName = v; } /** * Get the database url * * @return The DatabaseUrl value */ public String getDatabaseUrl() { return databaseUrl; } /** * Set the database url * * @param v The new DatabaseUrl value */ public void setDatabaseUrl(String v) { databaseUrl = v; } /** * Get the database driver name * * @return String database driver name */ public String getDatabaseDriver() { return databaseDriver; } /** * Set the database driver name * * @param v The new DatabaseDriver value */ public void setDatabaseDriver(String v) { databaseDriver = v; } /** * Get the database user * * @return String database user */ public String getDatabaseUser() { return databaseUser; } /** * Set the database user * * @param v The new DatabaseUser value */ public void setDatabaseUser(String v) { databaseUser = v; } /** * Get the database password * * @return String database password */ public String getDatabasePassword() { return databasePassword; } /** * Set the database password * * @param v The new DatabasePassword value */ public void setDatabasePassword(String v) { databasePassword = v; } /** * Initializes initial context * * @return Description of the Returned Value */ public Context initControlContext() throws Exception { super.initControlContext(); context.put("dataset", "all"); StringBuffer buf = new StringBuffer("Database settings:\n") .append(" driver: ").append(databaseDriver).append('\n') .append(" URL: ").append(databaseUrl).append('\n') .append(" user: ").append(databaseUser).append('\n') .append(" password: ").append(databasePassword).append('\n'); log(buf.toString(), Project.MSG_DEBUG); try { Class.forName(databaseDriver); log("DB driver instantiated sucessfuly", Project.MSG_DEBUG); conn = DriverManager.getConnection( databaseUrl, databaseUser, databasePassword); log("DB connection established", Project.MSG_DEBUG); context.put("tableTool", new TableTool()); } catch (SQLException se) { System.err.println("SQLException while connecting to DB:"); se.printStackTrace(); } catch (ClassNotFoundException cnfe) { System.err.println("cannot load driver:"); cnfe.printStackTrace(); } return context; } /** * Closes rs and conn, overriding the * cleanup() hook method in TexenTask. * * @exception Exception Database problem while closing resource. */ protected void cleanup() throws Exception { if (stmt != null) { stmt.close(); } if (conn != null) { conn.close(); } } /** * A nasty do-it-all tool class. It serves as: *
    *
  • context tool to fetch a table iterator
  • *
  • the abovenamed iterator which iterates over the table
  • *
  • getter for the table fields
  • *
* * @author fedor */ public class TableTool implements Iterator { private QueryDataSet qds; private boolean isEmpty; private int curIndex = -1; private Record curRec = null; /** * Constructor for the TableTool object */ public TableTool() { } /** * Constructor for the TableTool object * * @param rs Description of Parameter * @exception SQLException Problem using database record set * cursor. */ protected TableTool(QueryDataSet qds) throws Exception { this.qds = qds; this.qds.fetchRecords(); this.isEmpty = !(qds.size() > 0); } /** * Fetches an Iterator for the data in the named * table. * * @param tableName Description of Parameter * @return Iterator for the fetched data. * @exception SQLException Problem creating connection or * executing query. */ public TableTool fetch(String tableName) throws Exception { log("Fetching data for table " + tableName, Project.MSG_INFO); // Set Statement object in associated TorqueDataDump // instance return new TableTool (new QueryDataSet(conn, "SELECT * FROM " + tableName)); } /** * Description of the Method * * @return Description of the Returned Value */ public boolean hasNext() { try { return ((this.curIndex < this.qds.size() - 1) && (!isEmpty)); } catch (Exception se) { System.err.println("Exception :"); se.printStackTrace(); } return false; } /** * load the next record from the QueryDataSet * * @return Description of the Returned Value * @exception NoSuchElementException Description of Exception */ public Object next() throws NoSuchElementException { try { System.err.print("."); this.curRec = this.qds.getRecord(++curIndex); } catch (Exception se) { System.err.println("Exception while iterating:"); se.printStackTrace(); throw new NoSuchElementException(se.getMessage()); } return this; } /** * Retruns the value for the column * * @param columnName name of the column * @return value of the column or null if it doesn't exist */ public String get(String columnName) { try { return(this.curRec.getValue(columnName).asString()); } catch (Exception se) { log("Exception fetching value " + columnName + ": " + se.getMessage(), Project.MSG_ERR); } return null; } /** * unsupported! always throws Exception * * @exception UnsupportedOperationException */ public void remove() throws UnsupportedOperationException { throw new UnsupportedOperationException(); } } } 1.1 jakarta-commons-sandbox/sql/src/java/org/apache/commons/sql/task/JDBCTransformTask.java Index: JDBCTransformTask.java =================================================================== package org.apache.commons.sql.task; /* ==================================================================== * The Apache Software License, Version 1.1 * * Copyright (c) 2001 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Apache" and "Apache Software Foundation" and * "Apache Turbine" must not be used to endorse or promote products * derived from this software without prior written permission. For * written permission, please contact apache@apache.org. * * 5. Products derived from this software may not be called "Apache", * "Apache Turbine", nor may "Apache" appear in their name, without * prior written permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . */ import java.io.FileOutputStream; import java.io.PrintWriter; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.Types; import java.sql.SQLException; import java.util.Hashtable; import java.util.List; import java.util.Vector; import java.util.Collection; import java.util.Iterator; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Task; import org.apache.xerces.dom.DocumentImpl; import org.apache.xerces.dom.DocumentTypeImpl; import org.apache.xml.serialize.OutputFormat; import org.apache.xml.serialize.Method; import org.apache.xml.serialize.XMLSerializer; import org.w3c.dom.Element; import org.w3c.dom.Node; /** * This class generates an XML schema of an existing database from * JDBC metadata. * * @author Jason van Zyl * @author Fedor Karpelevitch * @version $Id: TorqueJDBCTransformTask.java,v 1.7 2002/04/11 22:02:06 mpoeschl Exp $ */ public class JDBCTransformTask extends Task { /** Name of XML database schema produced. */ protected String xmlSchema; /** JDBC URL. */ protected String dbUrl; /** JDBC driver. */ protected String dbDriver; /** JDBC user name. */ protected String dbUser; /** JDBC password. */ protected String dbPassword; /** DB schema to use. */ protected String dbSchema; /** DOM document produced. */ protected DocumentImpl doc; protected Node database, appData; /** Hashtable of columns that have primary keys. */ protected Hashtable primaryKeys; /** Hashtable to track what table a column belongs to. */ protected Hashtable columnTableMap; protected boolean sameJavaName; XMLSerializer xmlSerializer; public String getDbSchema() { return dbSchema; } public void setDbSchema(String dbSchema) { this.dbSchema = dbSchema; } public void setDbUrl(String v) { dbUrl = v; } public void setDbDriver(String v) { dbDriver = v; } public void setDbUser(String v) { dbUser = v; } public void setDbPassword(String v) { dbPassword = v; } public void setOutputFile (String v) { xmlSchema = v; } public void setSameJavaName(boolean v) { this.sameJavaName = v; } public boolean isSameJavaName() { return this.sameJavaName; } /** * Default constructor. */ public void execute() throws BuildException { System.err.println("Torque - JDBCToXMLSchema starting\n"); System.err.println("Your DB settings are:"); System.err.println("driver : " + dbDriver); System.err.println("URL : " + dbUrl); System.err.println("user : " + dbUser); System.err.println("password : " + dbPassword); System.err.println("schema : " + dbSchema); DocumentTypeImpl docType= new DocumentTypeImpl(null, "app-data", null, "http://jakarta.apache.org/turbine/dtd/database.dtd"); doc = new DocumentImpl(docType); doc.appendChild(doc.createComment(" Autogenerated by JDBCToXMLSchema! ")); try { generateXML(); xmlSerializer = new XMLSerializer( new PrintWriter( new FileOutputStream(xmlSchema)), new OutputFormat(Method.XML, null, true)); xmlSerializer.serialize(doc); } catch (Exception e) { System.err.println(e); e.printStackTrace(); } System.err.println("\nTorque - JDBCToXMLSchema finished"); } /** * Generates an XML database schema from JDBC metadata. * * @exception Exception, a generic exception. */ public void generateXML() throws Exception { // Load the Interbase Driver. Class.forName(dbDriver); System.err.println("DB driver sucessfuly instantiated"); // Attemtp to connect to a database. Connection con = DriverManager.getConnection(dbUrl, dbUser, dbPassword); System.err.println("DB connection established"); // Get the database Metadata. DatabaseMetaData dbMetaData = con.getMetaData(); // The database map. List tableList = getTableNames(dbMetaData); appData = doc.createElement("app-data"); database = doc.createElement("database"); // Build a database-wide column -> table map. columnTableMap = new Hashtable(); log("Building column/table map..."); for (int i = 0; i < tableList.size(); i++) { String curTable = (String) tableList.get(i); List columns = getColumns(dbMetaData, curTable); for (int j = 0; j < columns.size(); j++) { List col = (List) columns.get(j); String name = (String) col.get(0); columnTableMap.put(name, curTable); } } for (int i = 0; i < tableList.size(); i++) { // Add Table. String curTable = (String) tableList.get(i); // dbMap.addTable(curTable); log("Processing table: " + curTable); Element table = doc.createElement("table"); table.setAttribute("name", curTable); if (isSameJavaName()) { table.setAttribute("javaName", curTable); } // Add Columns. // TableMap tblMap = dbMap.getTable(curTable); List columns = getColumns(dbMetaData, curTable); List primKeys = getPrimaryKeys(dbMetaData, curTable); Collection forgnKeys = getForeignKeys(dbMetaData, curTable); // Set the primary keys. primaryKeys = new Hashtable(); for (int k = 0; k < primKeys.size(); k++) { String curPrimaryKey = (String) primKeys.get(k); primaryKeys.put(curPrimaryKey, curPrimaryKey); } for (int j = 0; j < columns.size(); j++) { List col = (List) columns.get(j); String name = (String) col.get(0); Integer type = ((Integer) col.get(1)); int size = ((Integer) col.get(2)).intValue(); // From DatabaseMetaData.java // // Indicates column might not allow NULL values. Huh? // Might? Boy, that's a definitive answer. /* int columnNoNulls = 0; */ // Indicates column definitely allows NULL values. /* int columnNullable = 1; */ // Indicates NULLABILITY of column is unknown. /* int columnNullableUnknown = 2; */ Integer nullType = (Integer) col.get(3); String defValue = (String) col.get(4); Element column = doc.createElement("column"); column.setAttribute("name", name); if (isSameJavaName()) { column.setAttribute("javaName", name); } column.setAttribute("type", TypeMap.getTorqueType(type)); if (size > 0 && (type.intValue() == Types.CHAR || type.intValue() == Types.VARCHAR || type.intValue() == Types.LONGVARCHAR)) { column.setAttribute("size", new Integer(size).toString()); } if (nullType.intValue() == 0) { column.setAttribute("required", "true"); } if (primaryKeys.containsKey(name)) { column.setAttribute("primaryKey", "true"); } if (defValue!=null) { // trim out parens & quotes out of def value. // makes sense for MSSQL. not sure about others. if (defValue.startsWith("(") && defValue.endsWith(")")) { defValue = defValue.substring(1, defValue.length() - 1); } if (defValue.startsWith("'") && defValue.endsWith("'")) { defValue = defValue.substring(1, defValue.length() - 1); } column.setAttribute("default", defValue); } table.appendChild(column); } // Foreign keys for this table. for (Iterator l = forgnKeys.iterator(); l.hasNext();) { Object[] forKey = (Object[]) l.next(); String foreignKeyTable = (String)forKey[0]; List refs = (List) forKey[1]; Element fk = doc.createElement("foreign-key"); fk.setAttribute("foreignTable", foreignKeyTable); for (int m = 0; m < refs.size(); m++) { Element ref = doc.createElement("reference"); String[] refData = (String[]) refs.get(m); ref.setAttribute("local", refData[0]); ref.setAttribute("foreign", refData[1]); fk.appendChild(ref); } table.appendChild(fk); } database.appendChild(table); } appData.appendChild(database); doc.appendChild(appData); } /** * Get all the table names in the current database that are not * system tables. * * @param dbMeta JDBC database metadata. * @return The list of all the tables in a database. * @exception SQLException */ public List getTableNames(DatabaseMetaData dbMeta) throws SQLException { log("Getting table list..."); List tables = new Vector(); ResultSet tableNames = null; // these are the entity types we want from the database String[] types = {"TABLE", "VIEW"}; try { tableNames = dbMeta.getTables(null, dbSchema, "%", types); while (tableNames.next()) { String name = tableNames.getString(3); String type = tableNames.getString(4); tables.add(name); } } finally { if (tableNames != null) { tableNames.close(); } } return tables; } /** * Retrieves all the column names and types for a given table from * JDBC metadata. It returns a vector of vectors. Each element * of the returned vector is a vector with: * * element 0 => a String object for the column name. * element 1 => an Integer object for the column type. * element 2 => size of the column. * element 3 => null type. * * @param dbMeta JDBC metadata. * @param tableName Table from which to retrieve column * information. * @return The list of columns in tableName. */ public List getColumns(DatabaseMetaData dbMeta, String tableName) throws SQLException { List columns = new Vector(); ResultSet columnSet = null; try { columnSet = dbMeta.getColumns(null, dbSchema, tableName, null); while (columnSet.next()) { String name = columnSet.getString(4); Integer sqlType = new Integer(columnSet.getString(5)); Integer size = new Integer(columnSet.getInt(7)); Integer nullType = new Integer(columnSet.getInt(11)); String defValue = columnSet.getString(13); List col = new Vector(5); col.add(name); col.add(sqlType); col.add(size); col.add(nullType); col.add(defValue); columns.add(col); } } finally { if (columnSet != null) { columnSet.close(); } } return columns; } /** * Retrieves a list of the columns composing the primary key for a given * table. * * @param dbMeta JDBC metadata. * @param tableName Table from which to retrieve PK information. * @return A list of the primary key parts for tableName. */ public List getPrimaryKeys(DatabaseMetaData dbMeta, String tableName) throws SQLException { List pk = new Vector(); ResultSet parts = null; try { parts = dbMeta.getPrimaryKeys(null, dbSchema, tableName); while (parts.next()) { pk.add(parts.getString(4)); } } finally { if (parts != null) { parts.close(); } } return pk; } /** * Retrieves a list of foreign key columns for a given table. * * @param dbMeta JDBC metadata. * @param tableName Table from which to retrieve FK information. * @return A list of foreign keys in tableName. */ public Collection getForeignKeys(DatabaseMetaData dbMeta, String tableName) throws SQLException { Hashtable fks = new Hashtable(); ResultSet foreignKeys = null; try { foreignKeys = dbMeta.getImportedKeys(null, dbSchema, tableName); while (foreignKeys.next()) { String fkName = foreignKeys.getString(12); // if FK has no name - make it up (use tablename instead) if (fkName == null) { fkName = foreignKeys.getString(3); } Object[] fk = (Object[])fks.get(fkName); List refs; if (fk == null) { fk = new Object[2]; fk[0] = foreignKeys.getString(3); //referenced table name refs = new Vector(); fk[1] = refs; fks.put(fkName, fk); } else { refs = (Vector)fk[1]; } String[] ref = new String[2]; ref[0] = foreignKeys.getString(8); //local column ref[1] = foreignKeys.getString(4); //foreign column refs.add(ref); } } finally { if (foreignKeys != null) { foreignKeys.close(); } } return fks.values(); } } 1.1 jakarta-commons-sandbox/sql/src/java/org/apache/commons/sql/task/DocumentationTask.java Index: DocumentationTask.java =================================================================== package org.apache.commons.sql.task; /* ==================================================================== * The Apache Software License, Version 1.1 * * Copyright (c) 2001 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Apache" and "Apache Software Foundation" and * "Apache Turbine" must not be used to endorse or promote products * derived from this software without prior written permission. For * written permission, please contact apache@apache.org. * * 5. Products derived from this software may not be called "Apache", * "Apache Turbine", nor may "Apache" appear in their name, without * prior written permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . */ import org.apache.velocity.context.Context; /** * An ant task for generating output by using Velocity * * @author Martin Poeschl * @version $Id: TorqueDocumentationTask.java,v 1.2 2002/04/11 22:02:06 mpoeschl Exp $ */ public class DocumentationTask extends DataModelTask { /** * The target database(s) we are generating SQL * for. Right now we can only deal with a single * target, but we will support multiple targets * soon. */ private String targetDatabase; private String outputFormat; /** * Get the current target package. * * @return String target database(s) */ public String getTargetDatabase() { return targetDatabase; } /** * Set the current target package. This is where * generated java classes will live. * * @param v target database(s) */ public void setTargetDatabase(String v) { targetDatabase = v; } /** * Get the current output format. * * @return the current output format */ public String getOutputFormat() { return outputFormat; } /** * Set the current output format. * * @param v output format */ public void setOutputFormat(String v) { outputFormat = v; } /** * Place our target package value into the context for use in the templates. */ public Context initControlContext() throws Exception { super.initControlContext(); context.put("targetDatabase", targetDatabase); context.put("outputFormat", outputFormat); return context; } } 1.1 jakarta-commons-sandbox/sql/src/java/org/apache/commons/sql/task/TypeMap.java Index: TypeMap.java =================================================================== package org.apache.commons.sql.task; /* ==================================================================== * The Apache Software License, Version 1.1 * * Copyright (c) 2001 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Apache" and "Apache Software Foundation" and * "Apache Turbine" must not be used to endorse or promote products * derived from this software without prior written permission. For * written permission, please contact apache@apache.org. * * 5. Products derived from this software may not be called "Apache", * "Apache Turbine", nor may "Apache" appear in their name, without * prior written permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . */ import java.util.Hashtable; import java.sql.Types; // I don't know if the peer system deals // with the recommended mappings. // //import java.sql.Date; //import java.sql.Time; //import java.sql.Timestamp; /** * A class that maps JDBC types to their corresponding * Java object types, and Java native types. Used * by Column.java to perform object/native mappings. * * These are the official SQL type to Java type mappings. * These don't quite correspond to the way the peer * system works so we'll have to make some adjustments. *
   * -------------------------------------------------------
   * SQL Type      | Java Type            | Peer Type
   * -------------------------------------------------------
   * CHAR          | String               | String
   * VARCHAR       | String               | String
   * LONGVARCHAR   | String               | String
   * NUMERIC       | java.math.BigDecimal | java.math.BigDecimal
   * DECIMAL       | java.math.BigDecimal | java.math.BigDecimal
   * BIT           | boolean OR Boolean   | Boolean
   * TINYINT       | byte OR Byte         | Byte
   * SMALLINT      | short OR Short       | Short
   * INTEGER       | int OR Integer       | Integer
   * BIGINT        | long OR Long         | Long
   * REAL          | float OR Float       | Float
   * FLOAT         | double OR Double     | Double
   * DOUBLE        | double OR Double     | Double
   * BINARY        | byte[]               | ?
   * VARBINARY     | byte[]               | ?
   * LONGVARBINARY | byte[]               | ?
   * DATE          | java.sql.Date        | java.util.Date
   * TIME          | java.sql.Time        | java.util.Date
   * TIMESTAMP     | java.sql.Timestamp   | java.util.Date
   *
   * -------------------------------------------------------
   * A couple variations have been introduced to cover cases
   * that may arise, but are not covered above
   * BOOLEANCHAR   | boolean OR Boolean   | String
   * BOOLEANINT    | boolean OR Boolean   | Integer
   * 
* * @author Jason van Zyl * @version $Id: TypeMap.java,v 1.5 2002/04/11 22:02:06 mpoeschl Exp $ */ public class TypeMap { public static final String CHAR = "CHAR"; public static final String VARCHAR = "VARCHAR"; public static final String LONGVARCHAR = "LONGVARCHAR"; public static final String CLOB = "CLOB"; public static final String NUMERIC = "NUMERIC"; public static final String DECIMAL = "DECIMAL"; public static final String BIT = "BIT"; public static final String TINYINT = "TINYINT"; public static final String SMALLINT = "SMALLINT"; public static final String INTEGER = "INTEGER"; public static final String BIGINT = "BIGINT"; public static final String REAL = "REAL"; public static final String FLOAT = "FLOAT"; public static final String DOUBLE = "DOUBLE"; public static final String BINARY = "BINARY"; public static final String VARBINARY = "VARBINARY"; public static final String LONGVARBINARY = "LONGVARBINARY"; public static final String BLOB = "BLOB"; public static final String DATE = "DATE"; public static final String TIME = "TIME"; public static final String TIMESTAMP = "TIMESTAMP"; public static final String BOOLEANCHAR = "BOOLEANCHAR"; public static final String BOOLEANINT = "BOOLEANINT"; private static final String[] TEXT_TYPES = { CHAR, VARCHAR, LONGVARCHAR, CLOB, DATE, TIME, TIMESTAMP, BOOLEANCHAR }; private static Hashtable torqueTypeToJdbcTypeMap = null; private static Hashtable jdbcToTorqueTypeMap = null; private static boolean isInitialized = false; /** * Initializes the SQL to Java map so that it * can be used by client code. */ public synchronized static void initialize() { if (isInitialized == false) { /* * Create JDBC -> Java object mappings. */ torqueTypeToJdbcTypeMap = new Hashtable(); torqueTypeToJdbcTypeMap.put(CHAR, CHAR); torqueTypeToJdbcTypeMap.put(VARCHAR, VARCHAR); torqueTypeToJdbcTypeMap.put(LONGVARCHAR, LONGVARCHAR); torqueTypeToJdbcTypeMap.put(CLOB, CLOB); torqueTypeToJdbcTypeMap.put(NUMERIC, NUMERIC); torqueTypeToJdbcTypeMap.put(DECIMAL, DECIMAL); torqueTypeToJdbcTypeMap.put(BIT, BIT); torqueTypeToJdbcTypeMap.put(TINYINT, TINYINT); torqueTypeToJdbcTypeMap.put(SMALLINT, SMALLINT); torqueTypeToJdbcTypeMap.put(INTEGER, INTEGER); torqueTypeToJdbcTypeMap.put(BIGINT, BIGINT); torqueTypeToJdbcTypeMap.put(REAL, REAL); torqueTypeToJdbcTypeMap.put(FLOAT, FLOAT); torqueTypeToJdbcTypeMap.put(DOUBLE, DOUBLE); torqueTypeToJdbcTypeMap.put(BINARY, BINARY); torqueTypeToJdbcTypeMap.put(VARBINARY, VARBINARY); torqueTypeToJdbcTypeMap.put(LONGVARBINARY, LONGVARBINARY); torqueTypeToJdbcTypeMap.put(BLOB, BLOB); torqueTypeToJdbcTypeMap.put(DATE, DATE); torqueTypeToJdbcTypeMap.put(TIME, TIME); torqueTypeToJdbcTypeMap.put(TIMESTAMP, TIMESTAMP); /* * Create JDBC type code to torque type map. */ jdbcToTorqueTypeMap = new Hashtable(); jdbcToTorqueTypeMap.put(new Integer(Types.CHAR), CHAR); jdbcToTorqueTypeMap.put(new Integer(Types.VARCHAR), VARCHAR); jdbcToTorqueTypeMap.put(new Integer(Types.LONGVARCHAR), LONGVARCHAR); jdbcToTorqueTypeMap.put(new Integer(Types.CLOB), CLOB); jdbcToTorqueTypeMap.put(new Integer(Types.NUMERIC), NUMERIC); jdbcToTorqueTypeMap.put(new Integer(Types.DECIMAL), DECIMAL); jdbcToTorqueTypeMap.put(new Integer(Types.BIT), BIT); jdbcToTorqueTypeMap.put(new Integer(Types.TINYINT), TINYINT); jdbcToTorqueTypeMap.put(new Integer(Types.SMALLINT), SMALLINT); jdbcToTorqueTypeMap.put(new Integer(Types.INTEGER), INTEGER); jdbcToTorqueTypeMap.put(new Integer(Types.BIGINT), BIGINT); jdbcToTorqueTypeMap.put(new Integer(Types.REAL), REAL); jdbcToTorqueTypeMap.put(new Integer(Types.FLOAT), FLOAT); jdbcToTorqueTypeMap.put(new Integer(Types.DOUBLE), DOUBLE); jdbcToTorqueTypeMap.put(new Integer(Types.BINARY), BINARY); jdbcToTorqueTypeMap.put(new Integer(Types.VARBINARY), VARBINARY); jdbcToTorqueTypeMap.put(new Integer(Types.LONGVARBINARY), LONGVARBINARY); jdbcToTorqueTypeMap.put(new Integer(Types.BLOB), BLOB); jdbcToTorqueTypeMap.put(new Integer(Types.DATE), DATE); jdbcToTorqueTypeMap.put(new Integer(Types.TIME), TIME); jdbcToTorqueTypeMap.put(new Integer(Types.TIMESTAMP), TIMESTAMP); isInitialized = true; } } /** * Report whether this object has been initialized. */ public static boolean isInitialized() { return isInitialized; } /** * Returns the correct jdbc type for torque added types */ public static String getJdbcType(String type) { // Make sure the we are initialized. if (isInitialized == false) { initialize(); } return (String) torqueTypeToJdbcTypeMap.get(type); } /** * Returns Torque type constant corresponding to JDBC type code. * Used but Torque JDBC task. */ public static String getTorqueType(Integer sqlType) { // Make sure the we are initialized. if (isInitialized == false) { initialize(); } return (String) jdbcToTorqueTypeMap.get(sqlType); } /** * Returns true if values for the type need to be quoted. * * @param type The type to check. */ public static final boolean isTextType(String type) { for (int i = 0; i < TEXT_TYPES.length; i++) { if (type.equals(TEXT_TYPES[i])) { return true; } } // If we get this far, there were no matches. return false; } } 1.1 jakarta-commons-sandbox/sql/src/java/org/apache/commons/sql/task/DataModelTask.java Index: DataModelTask.java =================================================================== package org.apache.commons.sql.task; /* ==================================================================== * The Apache Software License, Version 1.1 * * Copyright (c) 2001 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Apache" and "Apache Software Foundation" and * "Apache Turbine" must not be used to endorse or promote products * derived from this software without prior written permission. For * written permission, please contact apache@apache.org. * * 5. Products derived from this software may not be called "Apache", * "Apache Turbine", nor may "Apache" appear in their name, without * prior written permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . */ import java.io.File; import java.util.Hashtable; import java.util.Iterator; import java.util.Vector; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.DirectoryScanner; import org.apache.tools.ant.types.FileSet; import org.apache.velocity.context.Context; import org.apache.velocity.VelocityContext; import org.apache.velocity.texen.ant.TexenTask; /** * A base torque task that uses either a single XML schema * representing a data model, or a <fileset> of XML schemas. * We are making the assumption that an XML schema representing * a data model contains tables for a single * database. * * @author Jason van Zyl * @author Daniel Rall */ public class DataModelTask extends TexenTask { /** * XML that describes the database model, this is transformed * into the application model object. */ protected String xmlFile; /** * Fileset of XML schemas which represent our data models. */ protected Vector filesets = new Vector(); /** * Data models that we collect. One from each XML schema file. */ protected Vector dataModels = new Vector(); /** * Velocity context which exposes our objects * in the templates. */ protected Context context; /** * Map of data model name to database name. * Should probably stick to the convention * of them being the same but I know right now * in a lot of cases they won't be. */ protected Hashtable dataModelDbMap; /** * Hashtable containing the names of all the databases * in our collection of schemas. */ protected Hashtable databaseNames; //!! This is probably a crappy idea having the sql file -> db map // here. I can't remember why I put it here at the moment ... // maybe I was going to map something else. It can probably // move into the SQL task. /** * Name of the properties file that maps an SQL file * to a particular database. */ protected String sqldbmap; /** * The path to properties file containing db idiosyncrasies is * constructed by appending the "getTargetDatabase()/db.props * to this path. */ private String basePathToDbProps; /** * The target database(s) we are generating SQL * for. Right now we can only deal with a single * target, but we will support multiple targets * soon. */ private String targetDatabase; /** * Set the sqldbmap. * * @param sqldbmap th db map */ public void setSqlDbMap(String sqldbmap) { //!! Make all these references files not strings. this.sqldbmap = project.resolveFile(sqldbmap).toString(); } /** * Get the sqldbmap. * * @return String sqldbmap. */ public String getSqlDbMap() { return sqldbmap; } /** * Return the data models that have been * processed. * * @return Vector data models */ public Vector getDataModels() { return dataModels; } /** * Return the data model to database name map. * * @return Hashtable data model name to database name map. */ public Hashtable getDataModelDbMap() { return dataModelDbMap; } /** * Get the xml schema describing the application model. * * @return String xml schema file. */ public String getXmlFile() { return xmlFile; } /** * Set the xml schema describing the application model. * * @param xmlFile The new XmlFile value */ public void setXmlFile(String xmlFile) { this.xmlFile = project.resolveFile(xmlFile).toString(); } /** * Adds a set of files (nested fileset attribute). */ public void addFileset(FileSet set) { filesets.addElement(set); } /** * Get the current target package. * * @return String target database(s) */ public String getTargetDatabase() { return targetDatabase; } /** * Set the current target package. This is where * generated java classes will live. * * @param v target database(s) */ public void setTargetDatabase(String v) { targetDatabase = v; } /** * The path to properties file containing db idiosyncrasies is * constructed by appending the "getTargetDatabase()/db.props * to this path. */ public String getBasePathToDbProps() { return basePathToDbProps; } /** * The path to properties file containing db idiosyncrasies is * constructed by appending the "getTargetDatabase()/db.props * to this path. */ public void setBasePathToDbProps(String v) { this.basePathToDbProps = v; } /** * Set up the initialial context for generating the SQL from the XML schema. * * @return Description of the Returned Value */ public Context initControlContext() throws Exception { if (xmlFile == null && filesets.isEmpty()) { throw new BuildException("You must specify an XML schema or " + "fileset of XML schemas!"); } if (xmlFile != null) { // Transform the XML database schema into // data model object. //dataModels.addElement(ad); } else { // Deal with the filesets. for (int i = 0; i < filesets.size(); i++) { FileSet fs = (FileSet) filesets.elementAt(i); DirectoryScanner ds = fs.getDirectoryScanner(project); File srcDir = fs.getDir(project); String[] dataModelFiles = ds.getIncludedFiles(); // Make a transaction for each file for (int j = 0; j < dataModelFiles.length; j++) { //dataModels.addElement(ad); } } } Iterator i = dataModels.iterator(); databaseNames = new Hashtable(); dataModelDbMap = new Hashtable(); // Different datamodels may state the same database // names, we just want the unique names of databases. /* while (i.hasNext()) { AppData ad = (AppData) i.next(); Database database = ad.getDatabase(); databaseNames.put(database.getName(), database.getName()); dataModelDbMap.put(ad.getName(), database.getName()); } */ // Create a new Velocity context. context = new VelocityContext(); // Place our set of data models into the context along // with the names of the databases as a convenience for // now. context.put("dataModels", dataModels); context.put("databaseNames", databaseNames); return context; } /** * Gets a name to use for the application's data model. * * @param xmlFile The path to the XML file housing the data model. * @return The name to use for the AppData. */ private String grokName(String xmlFile) { // This can't be set from the file name as it is an unreliable // method of naming the descriptor. Not everyone uses the same // method as I do in the TDK. jvz. String name = "data-model"; int i = xmlFile.lastIndexOf(System.getProperty("file.separator")); if (i != -1) { // Creep forward to the start of the file name. i++; int j = xmlFile.lastIndexOf('.'); if (i < j) { name = xmlFile.substring(i, j); } else { // Weirdo name = xmlFile.substring(i); } } return name; } } 1.1 jakarta-commons-sandbox/sql/src/java/org/apache/commons/sql/task/DataSQLTask.java Index: DataSQLTask.java =================================================================== package org.apache.commons.sql.task; /* ==================================================================== * The Apache Software License, Version 1.1 * * Copyright (c) 2001 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Apache" and "Apache Software Foundation" and * "Apache Turbine" must not be used to endorse or promote products * derived from this software without prior written permission. For * written permission, please contact apache@apache.org. * * 5. Products derived from this software may not be called "Apache", * "Apache Turbine", nor may "Apache" appear in their name, without * prior written permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . */ import java.io.FileInputStream; import java.io.FileOutputStream; import java.util.List; import java.util.Properties; import org.apache.velocity.context.Context; import org.apache.commons.sql.model.Database; /** * An extended Texen task used for generating SQL source from an XML data file * * @author Jason van Zyl * @author John McNally * @author Fedor Karpelevitch * @version $Id: TorqueDataSQLTask.java,v 1.8 2002/04/11 22:02:06 mpoeschl Exp $ */ public class DataSQLTask extends DataModelTask { private String dataXmlFile; private String dataDTD; /** * The target database(s) we are generating SQL for. Right now we can only * deal with a single target, but we will support multiple targets soon. */ private String targetDatabase; /** * Sets the DataXmlFile attribute of the TorqueDataSQLTask object * * @param dataXmlFile The new DataXmlFile value */ public void setDataXmlFile(String dataXmlFile) { this.dataXmlFile = project.resolveFile(dataXmlFile).toString(); } /** * Gets the DataXmlFile attribute of the TorqueDataSQLTask object * * @return The DataXmlFile value */ public String getDataXmlFile() { return dataXmlFile; } /** * Get the current target database. * * @return String target database(s) */ public String getTargetDatabase() { return targetDatabase; } /** * Set the current target database. This is where generated java classes * will live. * * @param v The new TargetDatabase value */ public void setTargetDatabase(String v) { targetDatabase = v; } /** * Gets the DataDTD attribute of the TorqueDataSQLTask object * * @return The DataDTD value */ public String getDataDTD() { return dataDTD; } /** * Sets the DataDTD attribute of the TorqueDataSQLTask object * * @param dataDTD The new DataDTD value */ public void setDataDTD(String dataDTD) { this.dataDTD = project.resolveFile(dataDTD).toString(); } /** * Set up the initialial context for generating the SQL from the XML schema. * * @return Description of the Returned Value */ public Context initControlContext() throws Exception { super.initControlContext(); /* AppData app = (AppData) getDataModels().elementAt(0); Database db = app.getDatabase(); try { XmlToData dataXmlParser = new XmlToData(db, dataDTD); List data = dataXmlParser.parseFile(dataXmlFile); context.put("data", data); } catch (Exception e) { throw new Exception("Exception parsing data XML:"); } // Place our model in the context. context.put("appData", app); */ Database db = null; // Place the target database in the context. context.put("targetDatabase", targetDatabase); Properties p = new Properties(); FileInputStream fis = new FileInputStream(getSqlDbMap()); p.load(fis); fis.close(); p.setProperty(getOutputFile(), db.getName()); p.store(new FileOutputStream(getSqlDbMap()), "Sqlfile -> Database map"); return context; } } 1.1 jakarta-commons-sandbox/sql/src/java/org/apache/commons/sql/task/DataDTDTask.java Index: DataDTDTask.java =================================================================== package org.apache.commons.sql.task; /* ==================================================================== * The Apache Software License, Version 1.1 * * Copyright (c) 2001 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Apache" and "Apache Software Foundation" and * "Apache Turbine" must not be used to endorse or promote products * derived from this software without prior written permission. For * written permission, please contact apache@apache.org. * * 5. Products derived from this software may not be called "Apache", * "Apache Turbine", nor may "Apache" appear in their name, without * prior written permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . */ /** * An extended Texen task used for generating data DTD from * an XML schema describing a database structure. * * @author Fedor Karpelevitch * @author Jason van Zyl * @version $Id: TorqueDataDTDTask.java,v 1.3 2001/10/27 19:04:38 jvanzyl Exp $ */ public class DataDTDTask extends DataModelTask { } 1.1 jakarta-commons-sandbox/sql/src/java/org/apache/commons/sql/task/SQLTask.java Index: SQLTask.java =================================================================== package org.apache.commons.sql.task; /* ==================================================================== * The Apache Software License, Version 1.1 * * Copyright (c) 2001 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Apache" and "Apache Software Foundation" and * "Apache Turbine" must not be used to endorse or promote products * derived from this software without prior written permission. For * written permission, please contact apache@apache.org. * * 5. Products derived from this software may not be called "Apache", * "Apache Turbine", nor may "Apache" appear in their name, without * prior written permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . */ import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.util.Properties; import java.util.Iterator; import org.apache.velocity.context.Context; import org.apache.velocity.VelocityContext; /** * An extended Texen task used for generating SQL source from * an XML schema describing a database structure. * * @author Jason van Zyl * @author database map Properties sqldbmap = new Properties(); // Check to see if the sqldbmap has already been created. File file = new File(getSqlDbMap()); if (file.exists()) { FileInputStream fis = new FileInputStream(file); sqldbmap.load(fis); fis.close(); } Iterator i = getDataModelDbMap().keySet().iterator(); while (i.hasNext()) { String dataModelName = (String) i.next(); String sqlFile = dataModelName + suffix + ".sql"; String databaseName; if (getDatabase() == null) { databaseName = (String) getDataModelDbMap().get(dataModelName); } else { databaseName = getDatabase(); } sqldbmap.setProperty(sqlFile,databaseName); } sqldbmap.store(new FileOutputStream(getSqlDbMap()),"Sqlfile -> Database map"); } /** * Place our target database and target platform * values into the context for use in the * templates. */ public Context initControlContext() throws Exception { super.initControlContext(); context.put("targetDatabase", getTargetDatabase()); createSqlDbMap(); return context; } } 1.1 jakarta-commons-sandbox/sql/src/java/org/apache/commons/sql/task/SQLExec.java Index: SQLExec.java =================================================================== package org.apache.commons.sql.task; /* * The Apache Software License, Version 1.1 * * Copyright (c) 1999-2002 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, if * any, must include the following acknowlegement: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowlegement may appear in the software itself, * if and wherever such third-party acknowlegements normally appear. * * 4. The names "The Jakarta Project", "Ant", and "Apache Software * Foundation" must not be used to endorse or promote products derived * from this software without prior written permission. For written * permission, please contact apache@apache.org. * * 5. Products derived from this software may not be called "Apache" * nor may "Apache" appear in their names without prior written * permission of the Apache Group. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . */ import java.io.BufferedOutputStream; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.FileReader; import java.io.PrintStream; import java.io.StringReader; import java.io.Reader; import java.util.ArrayList; import java.util.Iterator; import java.util.Enumeration; import java.util.Hashtable; import java.util.Vector; import java.util.Properties; import java.util.TreeSet; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.Driver; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.SQLWarning; import java.sql.Statement; import org.apache.commons.lang.StringUtils; import org.apache.tools.ant.AntClassLoader; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Project; import org.apache.tools.ant.ProjectHelper; import org.apache.tools.ant.Task; import org.apache.tools.ant.types.EnumeratedAttribute; import org.apache.tools.ant.types.Path; import org.apache.tools.ant.types.Reference; /** * This task uses an SQL -> Database map in the form of a properties * file to insert each SQL file listed into its designated database. * * @author Jeff Martin * @author Michael McCallum * @author Tim Stephenson * @author Jason van Zyl * @author Martin Poeschl * @version $Id: TorqueSQLExec.java,v 1.6 2002/04/11 22:02:07 mpoeschl Exp $ */ public class SQLExec extends Task { private int goodSql = 0; private int totalSql = 0; private Path classpath; private AntClassLoader loader; /** * */ static public class DelimiterType extends EnumeratedAttribute { static public final String NORMAL = "normal"; static public final String ROW = "row"; public String[] getValues() { return new String[] {NORMAL, ROW}; } } /** * Database connection */ private Connection conn = null; /** * Autocommit flag. Default value is false */ private boolean autocommit = false; /** * SQL statement */ private Statement statement = null; /** * DB driver. */ private String driver = null; /** * DB url. */ private String url = null; /** * User name. */ private String userId = null; /** * Password */ private String password = null; /** * SQL input command */ private String sqlCommand = ""; /** * SQL transactions to perform */ private Vector transactions = new Vector(); /** * SQL Statement delimiter */ private String delimiter = ";"; /** * The delimiter type indicating whether the delimiter will * only be recognized on a line by itself */ private String delimiterType = DelimiterType.NORMAL; /** * Print SQL results. */ private boolean print = false; /** * Print header columns. */ private boolean showheaders = true; /** * Results Output file. */ private File output = null; /** * RDBMS Product needed for this SQL. **/ private String rdbms = null; /** * RDBMS Version needed for this SQL. **/ private String version = null; /** * Action to perform if an error is found **/ private String onError = "abort"; /** * Encoding to use when reading SQL statements from a file */ private String encoding = null; /** * Src directory for the files listed in the sqldbmap. */ private String srcDir; /** * Properties file that maps an individual SQL * file to a database. */ private File sqldbmap; /** * Set the sqldbmap properties file. */ public void setSqlDbMap(String sqldbmap) { this.sqldbmap = project.resolveFile(sqldbmap); } /** * Get the sqldbmap properties file. */ public File getSqlDbMap() { return sqldbmap; } /** * Set the src directory for the sql files * listed in the sqldbmap file. */ public void setSrcDir(String srcDir) { this.srcDir = project.resolveFile(srcDir).toString(); } /** * Get the src directory for the sql files * listed in the sqldbmap file. */ public String getSrcDir() { return srcDir; } /** * Set the classpath for loading the driver. */ public void setClasspath(Path classpath) { if (this.classpath == null) { this.classpath = classpath; } else { this.classpath.append(classpath); } } /** * Create the classpath for loading the driver. */ public Path createClasspath() { if (this.classpath == null) { this.classpath = new Path(project); } return this.classpath.createPath(); } /** * Set the classpath for loading the driver using the classpath reference. */ public void setClasspathRef(Reference r) { createClasspath().setRefid(r); } /** * Set the sql command to execute */ public void addText(String sql) { this.sqlCommand += sql; } /** * Set the JDBC driver to be used. */ public void setDriver(String driver) { this.driver = driver; } /** * Set the DB connection url. */ public void setUrl(String url) { this.url = url; } /** * Set the user name for the DB connection. */ public void setUserid(String userId) { this.userId = userId; } /** * Set the file encoding to use on the sql files read in * * @param encoding the encoding to use on the files */ public void setEncoding(String encoding) { this.encoding = encoding; } /** * Set the password for the DB connection. */ public void setPassword(String password) { this.password = password; } /** * Set the autocommit flag for the DB connection. */ public void setAutocommit(boolean autocommit) { this.autocommit = autocommit; } /** * Set the statement delimiter. * *

For example, set this to "go" and delimitertype to "ROW" for * Sybase ASE or MS SQL Server.

*/ public void setDelimiter(String delimiter) { this.delimiter = delimiter; } /** * Set the Delimiter type for this sql task. The delimiter type takes two * values - normal and row. Normal means that any occurence of the delimiter * terminate the SQL command whereas with row, only a line containing just * the delimiter is recognized as the end of the command. */ public void setDelimiterType(DelimiterType delimiterType) { this.delimiterType = delimiterType.getValue(); } /** * Set the print flag. */ public void setPrint(boolean print) { this.print = print; } /** * Set the showheaders flag. */ public void setShowheaders(boolean showheaders) { this.showheaders = showheaders; } /** * Set the output file. */ public void setOutput(File output) { this.output = output; } /** * Set the rdbms required */ public void setRdbms(String vendor) { this.rdbms = vendor.toLowerCase(); } /** * Set the version required */ public void setVersion(String version) { this.version = version.toLowerCase(); } /** * Set the action to perform onerror */ public void setOnerror(OnError action) { this.onError = action.getValue(); } /** * Load the sql file and then execute it */ public void execute() throws BuildException { sqlCommand = sqlCommand.trim(); if (sqldbmap == null || getSqlDbMap().exists() == false) { throw new BuildException("You haven't provided an sqldbmap, or " + "the one you specified doesn't exist: " + sqldbmap); } if (driver == null) { throw new BuildException("Driver attribute must be set!", location); } if (userId == null) { throw new BuildException("User Id attribute must be set!", location); } if (password == null) { throw new BuildException("Password attribute must be set!", location); } if (url == null) { throw new BuildException("Url attribute must be set!", location); } Properties p = new Properties(); try { FileInputStream fis = new FileInputStream(getSqlDbMap()); p.load(fis); fis.close(); } catch (IOException ioe) { throw new BuildException("Cannot open and process the sqldbmap!"); } Hashtable h = new Hashtable(); TreeSet keys = new TreeSet(p.keySet()); for (Iterator e = keys.iterator(); e.hasNext();) { String sqlfile = (String) e.next(); String database = p.getProperty(sqlfile); ArrayList x = (ArrayList) h.get(database); if (x == null) { x = new ArrayList(); h.put(database, x); } // We want to make sure that the base schemas // are inserted first. if (sqlfile.indexOf("schema.sql") != -1) { x.add(0, sqlfile); } else { x.add(sqlfile); } } Iterator k = h.keySet().iterator(); while (k.hasNext()) { String db = (String) k.next(); ArrayList l = (ArrayList) h.get(db); Iterator j = l.iterator(); Vector ts = new Vector(); while (j.hasNext()) { String s = (String) j.next(); Transaction t = new Transaction(); t.setSrc(new File(srcDir,s)); ts.addElement(t); } insertDatabaseSqlFiles(url, db, ts); } } /** * Take the base url, the target database and insert a set of SQL * files into the target database. */ private void insertDatabaseSqlFiles(String url, String database, Vector transactions) { url = StringUtils.replace(url, "@DB@", database); System.out.println("Our new url -> " + url); Driver driverInstance = null; try { Class dc; if (classpath != null) { log( "Loading " + driver + " using AntClassLoader with classpath " + classpath, Project.MSG_VERBOSE ); loader = new AntClassLoader(project, classpath); dc = loader.loadClass(driver); } else { log("Loading " + driver + " using system loader.", Project.MSG_VERBOSE); dc = Class.forName(driver); } driverInstance = (Driver) dc.newInstance(); } catch (ClassNotFoundException e) { throw new BuildException("Class Not Found: JDBC driver " + driver + " could not be loaded", location); } catch (IllegalAccessException e) { throw new BuildException("Illegal Access: JDBC driver " + driver + " could not be loaded", location); } catch (InstantiationException e) { throw new BuildException("Instantiation Exception: JDBC driver " + driver + " could not be loaded", location); } try { log("connecting to " + url, Project.MSG_VERBOSE ); Properties info = new Properties(); info.put("user", userId); info.put("password", password); conn = driverInstance.connect(url, info); if (conn == null) { // Driver doesn't understand the URL throw new SQLException("No suitable Driver for " + url); } if (!isValidRdbms(conn)) { return; } conn.setAutoCommit(autocommit); statement = conn.createStatement(); PrintStream out = System.out; try { if (output != null) { log("Opening PrintStream to output file " + output, Project.MSG_VERBOSE); out = new PrintStream(new BufferedOutputStream( new FileOutputStream(output))); } // Process all transactions for (Enumeration e = transactions.elements(); e.hasMoreElements();) { ((Transaction) e.nextElement()).runTransaction(out); if (!autocommit) { log("Commiting transaction", Project.MSG_VERBOSE); conn.commit(); } } } finally { if (out != null && out != System.out) { out.close(); } } } catch (IOException e) { if (!autocommit && conn != null && onError.equals("abort")) { try { conn.rollback(); } catch (SQLException ex) { // do nothing. } } throw new BuildException(e, location); } catch (SQLException e) { if (!autocommit && conn != null && onError.equals("abort")) { try { conn.rollback(); } catch (SQLException ex) { // do nothing. } } throw new BuildException(e, location); } finally { try { if (statement != null) { statement.close(); } if (conn != null) { conn.close(); } } catch (SQLException e) {} } log(goodSql + " of " + totalSql + " SQL statements executed successfully"); } /** * * @param reader * @param out * @throws SQLException * @throws IOException */ protected void runStatements(Reader reader, PrintStream out) throws SQLException, IOException { String sql = ""; String line = ""; BufferedReader in = new BufferedReader(reader); try { while ((line = in.readLine()) != null) { line = line.trim(); line = ProjectHelper.replaceProperties(project, line, project.getProperties()); if (line.startsWith("//")) continue; if (line.startsWith("--")) continue; if (line.length() > 2 && line.substring(0,3).equalsIgnoreCase("REM")) continue; sql += " " + line; sql = sql.trim(); // SQL defines "--" as a comment to EOL // and in Oracle it may contain a hint // so we cannot just remove it, instead we must end it if (line.indexOf("--") >= 0) sql += "\n"; if (delimiterType.equals(DelimiterType.NORMAL) && sql.endsWith(delimiter) || delimiterType.equals(DelimiterType.ROW) && line.equals(delimiter)) { log("SQL: " + sql, Project.MSG_VERBOSE); execSQL(sql.substring(0, sql.length() - delimiter.length()), out); sql = ""; } } // Catch any statements not followed by ; if (!sql.equals("")) { execSQL(sql, out); } } catch (SQLException e) { throw e; } } /** * Verify if connected to the correct RDBMS */ protected boolean isValidRdbms(Connection conn) { if (rdbms == null && version == null) { return true; } try { DatabaseMetaData dmd = conn.getMetaData(); if (rdbms != null) { String theVendor = dmd.getDatabaseProductName().toLowerCase(); log("RDBMS = " + theVendor, Project.MSG_VERBOSE); if (theVendor == null || theVendor.indexOf(rdbms) < 0) { log("Not the required RDBMS: " + rdbms, Project.MSG_VERBOSE); return false; } } if (version != null) { String theVersion = dmd.getDatabaseProductVersion() .toLowerCase(); log("Version = " + theVersion, Project.MSG_VERBOSE); if (theVersion == null || !(theVersion.startsWith(version) || theVersion.indexOf(" " + version) >= 0)) { log("Not the required version: \"" + version + "\"", Project.MSG_VERBOSE); return false; } } } catch (SQLException e) { // Could not get the required information log("Failed to obtain required RDBMS information", Project.MSG_ERR); return false; } return true; } /** * Exec the sql statement. */ protected void execSQL(String sql, PrintStream out) throws SQLException { // Check and ignore empty statements if ("".equals(sql.trim())) return; try { totalSql++; if (!statement.execute(sql)) { log(statement.getUpdateCount() + " rows affected", Project.MSG_VERBOSE); } else { if (print) { printResults(out); } } SQLWarning warning = conn.getWarnings(); while (warning != null) { log(warning + " sql warning", Project.MSG_VERBOSE); warning = warning.getNextWarning(); } conn.clearWarnings(); goodSql++; } catch (SQLException e) { log("Failed to execute: " + sql, Project.MSG_ERR); if (!onError.equals("continue")) { throw e; } log(e.toString(), Project.MSG_ERR); } } /** * print any results in the statement. */ protected void printResults(PrintStream out) throws java.sql.SQLException { ResultSet rs = null; do { rs = statement.getResultSet(); if (rs != null) { log("Processing new result set.", Project.MSG_VERBOSE); ResultSetMetaData md = rs.getMetaData(); int columnCount = md.getColumnCount(); StringBuffer line = new StringBuffer(); if (showheaders) { for (int col = 1; col < columnCount; col++) { line.append(md.getColumnName(col)); line.append(","); } line.append(md.getColumnName(columnCount)); out.println(line); line.setLength(0); } while (rs.next()) { boolean first = true; for (int col = 1; col <= columnCount; col++) { String columnValue = rs.getString(col); if (columnValue != null) { columnValue = columnValue.trim(); } if (first) { first = false; } else { line.append(","); } line.append(columnValue); } out.println(line); line.setLength(0); } } } while (statement.getMoreResults()); out.println(); } /** * Enumerated attribute with the values "continue", "stop" and "abort" * for the onerror attribute. */ public static class OnError extends EnumeratedAttribute { public String[] getValues() { return new String[] {"continue", "stop", "abort"}; } } /** * Contains the definition of a new transaction element. * Transactions allow several files or blocks of statements * to be executed using the same JDBC connection and commit * operation in between. */ public class Transaction { private File tSrcFile = null; private String tSqlCommand = ""; public void setSrc(File src) { this.tSrcFile = src; } public void addText(String sql) { this.tSqlCommand += sql; } private void runTransaction(PrintStream out) throws IOException, SQLException { if (tSqlCommand.length() != 0) { log("Executing commands", Project.MSG_INFO); runStatements(new StringReader(tSqlCommand), out); } if (tSrcFile != null) { log("Executing file: " + tSrcFile.getAbsolutePath(), Project.MSG_INFO); Reader reader = (encoding == null) ? new FileReader(tSrcFile) : new InputStreamReader(new FileInputStream(tSrcFile), encoding); runStatements(reader, out); reader.close(); } } } } 1.1 jakarta-commons-sandbox/sql/src/java/org/apache/commons/sql/task/CreateDatabase.java Index: CreateDatabase.java =================================================================== package org.apache.commons.sql.task; /* ==================================================================== * The Apache Software License, Version 1.1 * * Copyright (c) 2001 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Apache" and "Apache Software Foundation" and * "Apache Turbine" must not be used to endorse or promote products * derived from this software without prior written permission. For * written permission, please contact apache@apache.org. * * 5. Products derived from this software may not be called "Apache", * "Apache Turbine", nor may "Apache" appear in their name, without * prior written permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . */ import org.apache.velocity.context.Context; /** * An extended Texen task used for generating simple scripts * for creating databases on various platforms. * * @author Jason van Zyl * @version $Id: TorqueCreateDatabase.java,v 1.6 2002/04/11 22:02:06 mpoeschl Exp $ */ public class CreateDatabase extends DataModelTask { /** * The target database vendor: MySQL, Oracle. */ private String targetDatabase; /** * Get the target database. * * @return String target database. */ public String getTargetDatabase() { return targetDatabase; } /** * Set the target database. * * @param String target database(s) */ public void setTargetDatabase(String v) { targetDatabase = v; } /** * Place our target database and target platform * values into the context for use in the * templates. */ public Context initControlContext() throws Exception { super.initControlContext(); context.put("targetDatabase", targetDatabase); return context; } } 1.2 +17 -17 jakarta-commons-sandbox/sql/src/jelly/createSql.jelly Index: createSql.jelly =================================================================== RCS file: /home/cvs/jakarta-commons-sandbox/sql/src/jelly/createSql.jelly,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- createSql.jelly 31 Jul 2002 17:00:00 -0000 1.1 +++ createSql.jelly 9 Sep 2002 13:47:57 -0000 1.2 @@ -17,23 +17,23 @@ Creating file: target/sql.xml - - - - - - - - - - - - - -
-
- -
+ + + + + + + + + + + + + +
+
+ +
1.2 +23 -23 jakarta-commons-sandbox/sql/src/jelly/defineTags.jelly Index: defineTags.jelly =================================================================== RCS file: /home/cvs/jakarta-commons-sandbox/sql/src/jelly/defineTags.jelly,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- defineTags.jelly 31 Jul 2002 17:00:00 -0000 1.1 +++ defineTags.jelly 9 Sep 2002 13:47:57 -0000 1.2 @@ -12,44 +12,44 @@ create table ${table.name} ( - - , - - + + , + + - + ) - + ${column.name} ${column.type} NOT NULL - - , + + , PRIMARY KEY( - - - - - - - - , - + + + + + + + + , + ${column.name} - - - ) - + + + ) + - - + + 1.1 jakarta-commons-sandbox/sql/src/test/org/apache/commons/sql/TestDataModelRoundTrip.java Index: TestDataModelRoundTrip.java =================================================================== package org.apache.commons.sql; /* * Copyright (C) The Apache Software Foundation. All rights reserved. * * This software is published under the terms of the Apache Software License * version 1.1, a copy of which has been included with this distribution in * the LICENSE file. * * $Id: TestProjectRoundTrip.java,v 1.3 2002/03/10 20:16:03 jvanzyl Exp $ */ import java.io.InputStream; import java.io.IOException; import java.io.FileInputStream; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import junit.textui.TestRunner; import org.apache.commons.betwixt.XMLIntrospector; import org.apache.commons.betwixt.io.BeanReader; import org.apache.commons.betwixt.io.BeanWriter; import org.apache.commons.betwixt.strategy.DecapitalizeNameMapper; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.impl.SimpleLog; import org.apache.commons.sql.model.*; /** * Test harness for the BeanReader that deals with project definitions. * * @author Jason van Zyl * @version $Revision: 1.3 $ */ public class TestDataModelRoundTrip extends TestCase { private String TEST_DOCUMENT; /** * A unit test suite for JUnit */ public static Test suite() { return new TestSuite(TestDataModelRoundTrip.class); } /** * Constructor for the TestDataModelRoundTrip object * * @param testName */ public TestDataModelRoundTrip(String testName) { super(testName); } /** * The JUnit setup method */ protected void setUp() throws Exception { super.setUp(); String baseDir = System.getProperty("basedir"); assertNotNull("The system property basedir was not defined.", baseDir); String fs = System.getProperty("file.separator"); assertNotNull("The system property file.separator was not defined.", fs); TEST_DOCUMENT = baseDir + "/src/test-input/datamodel.xml"; } /** * A unit test for JUnit */ public void testBeanWriter() throws Exception { BeanReader reader = new BeanReader(); reader.setXMLIntrospector(createXMLIntrospector()); reader.registerBeanClass(getBeanClass()); InputStream in = getXMLInput(); try { Database database = (Database) reader.parse(in); assertTrue("Parsed a Database object", database != null); assertEquals("bookstore", database.getName()); assertTrue("more than one table found", database.getTables().size() > 0 ); // Test our first table which is the 'book' table Table t0 = database.getTable(0); assertEquals("book", t0.getName()); Column c0 = t0.getColumn(0); assertEquals("book_id", c0.getName()); assertTrue("book_id is required", c0.isRequired()); assertTrue("book_id is primary key", c0.isPrimaryKey()); Column c1 = t0.getColumn(1); assertEquals("isbn", c1.getName()); assertTrue("isbn is required", c1.isRequired()); assertTrue("isbn is not primary key", ! c1.isPrimaryKey()); // Write out the bean //writeBean(database); } catch (Exception e) { e.printStackTrace(); fail(); } finally { if (in != null) { in.close(); } } } /** * Description of the Method */ public void writeBean(Object bean) throws Exception { BeanWriter writer = new BeanWriter(); writer.enablePrettyPrint(); writer.write(bean); } /** * @return the bean class to use as the root */ public Class getBeanClass() { return Database.class; } /** * Gets the xMLInput attribute of the TestDataModelRoundTrip object */ protected InputStream getXMLInput() throws IOException { //return getClass().getResourceAsStream("datamodel.xml"); return new FileInputStream(TEST_DOCUMENT); } /** * ### it would be really nice to move this somewhere shareable across Maven * / Turbine projects. Maybe a static helper method - question is what to * call it??? */ protected XMLIntrospector createXMLIntrospector() { XMLIntrospector introspector = new XMLIntrospector(); // set elements for attributes to true introspector.setAttributesForPrimitives(false); // turn bean elements into lower case introspector.setElementNameMapper(new DecapitalizeNameMapper()); return introspector; } } -- To unsubscribe, e-mail: For additional commands, e-mail: