You are viewing a plain text version of this content. The canonical link for it is here.
Posted to ojb-dev@db.apache.org by br...@apache.org on 2005/10/05 20:01:30 UTC

cvs commit: db-ojb/src/java/org/apache/ojb/broker/metadata DescriptorRepository.java

brj         2005/10/05 11:01:30

  Modified:    src/java/org/apache/ojb/broker/accesslayer Tag:
                        OJB_1_0_RELEASE RowReaderDefaultImpl.java
                        JdbcAccessImpl.java StatementsForClassImpl.java
                        RowReader.java ResultSetAndStatement.java
                        RsIterator.java
               src/java/org/apache/ojb/broker/accesslayer/sql Tag:
                        OJB_1_0_RELEASE SqlSelectStatement.java
                        SqlSelectByPkStatement.java SqlQueryStatement.java
                        SqlGenerator.java SqlGeneratorDefaultImpl.java
               src/java/org/apache/ojb/broker/util Tag: OJB_1_0_RELEASE
                        SqlHelper.java
               src/test/org/apache/ojb/broker Tag: OJB_1_0_RELEASE
                        InheritanceMultipleTableTest.java QueryTest.java
               src/test/org/apache/ojb/compare Tag: OJB_1_0_RELEASE
                        PerformanceJdbcFailoverTest.java
                        PerformanceJdbcTest.java
               src/java/org/apache/ojb/broker/core Tag: OJB_1_0_RELEASE
                        QueryReferenceBroker.java
               src/java/org/apache/ojb/broker/metadata Tag: OJB_1_0_RELEASE
                        DescriptorRepository.java
  Added:       src/java/org/apache/ojb/broker/accesslayer/sql Tag:
                        OJB_1_0_RELEASE SelectStatement.java
  Log:
  First try to fix OJB-63. The Creation of the PK-Query in SqlSelectByPkStatement needs improvement !
  Select CASE does not work with hsqldb 1.7.1
  
  Revision  Changes    Path
  No                   revision
  No                   revision
  1.30.2.6  +49 -21    db-ojb/src/java/org/apache/ojb/broker/accesslayer/RowReaderDefaultImpl.java
  
  Index: RowReaderDefaultImpl.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/accesslayer/RowReaderDefaultImpl.java,v
  retrieving revision 1.30.2.5
  retrieving revision 1.30.2.6
  diff -u -r1.30.2.5 -r1.30.2.6
  --- RowReaderDefaultImpl.java	14 Jun 2005 19:17:45 -0000	1.30.2.5
  +++ RowReaderDefaultImpl.java	5 Oct 2005 18:01:25 -0000	1.30.2.6
  @@ -24,6 +24,7 @@
   import org.apache.ojb.broker.metadata.ClassDescriptor;
   import org.apache.ojb.broker.metadata.FieldDescriptor;
   import org.apache.ojb.broker.util.ClassHelper;
  +import org.apache.ojb.broker.util.SqlHelper;
   
   /**
    * Default implementation of the {@link RowReader} interface.
  @@ -43,6 +44,7 @@
       private static final Object[] NO_ARGS = {};
   
       private ClassDescriptor m_cld;
  +    private boolean ojb_clazz =false;
   
       public RowReaderDefaultImpl(ClassDescriptor cld)
       {
  @@ -116,7 +118,16 @@
           }
   
           // 2. fill all scalar attributes of the new object
  -        FieldDescriptor[] fields = targetClassDescriptor.getFieldDescriptions();
  +        FieldDescriptor[] fields;
  +        if (ojb_clazz)
  +        {
  +            fields = targetClassDescriptor.getFieldDescriptor(true);
  +        }
  +        else
  +        {
  +            fields = targetClassDescriptor.getFieldDescriptor(true);            
  +        }
  +
           for (int i = 0; i < fields.length; i++)
           {
               fmd = fields[i];
  @@ -160,7 +171,7 @@
        *
        * @throws PersistenceBrokerException if there is an error accessing the access layer
        */
  -    public void readObjectArrayFrom(ResultSet rs, Map row)
  +    public void readObjectArrayFrom(ResultSetAndStatement rs_stmt, Map row)
       {
           FieldDescriptor[] fields = null;
   /*
  @@ -177,7 +188,7 @@
           }
           else
           {
  -            String ojbConcreteClass = extractOjbConcreteClass(m_cld, rs, row);
  +            String ojbConcreteClass = extractOjbConcreteClass(m_cld, rs_stmt.m_rs, row);
               /*
               arminw:
               if multiple classes were mapped to the same table, lookup the concrete
  @@ -185,35 +196,51 @@
               */
               if(ojbConcreteClass != null)
               {
  -                row.put(OJB_CONCRETE_CLASS_KEY, ojbConcreteClass);
                   ClassDescriptor cld = m_cld.getRepository().getDescriptorFor(ojbConcreteClass);
  -                fields = cld.getFieldDescriptions();
  +                row.put(OJB_CONCRETE_CLASS_KEY, cld.getClassOfObject());
  +                fields = cld.getFieldDescriptor(true);
               }
               else
               {
  -                // fields = m_cld.getRepository().getFieldDescriptorsForMultiMappedTable(m_cld);
  -                /*
  -                arminw:
  -                should be valid to use fields of class-descriptor, because we handle ojbConcreteClass
  -                above, so a multi mapped table class-descriptor will never be used here
  -                */
  -                fields = m_cld.getFieldDescriptions();
  -            }
  +                String ojbClass = SqlHelper.getOjbClassName(rs_stmt.m_rs);
  +                if (ojbClass != null)
  +                {
  +                    ClassDescriptor cld = m_cld.getRepository().getDescriptorFor(ojbClass);
  +                    row.put(OJB_CONCRETE_CLASS_KEY, cld.getClassOfObject());
  +                    fields = cld.getFieldDescriptor(true);
  +                }
  +                else
  +                {
  +                    fields = m_cld.getFieldDescriptor(true);
  +                }           
  +            }         
           }
  -        readValuesFrom(rs, row, fields);
  +        readValuesFrom(rs_stmt, row, fields);
       }
   
       /*
        * @see RowReader#readPkValuesFrom(ResultSet, ClassDescriptor, Map)
        * @throws PersistenceBrokerException if there is an error accessing the access layer
        */
  -    public void readPkValuesFrom(ResultSet rs, Map row)
  +    public void readPkValuesFrom(ResultSetAndStatement rs_stmt, Map row)
       {
  -        FieldDescriptor[] pkFields = m_cld.getPkFields();
  -        readValuesFrom(rs, row, pkFields);
  +        String ojbClass = SqlHelper.getOjbClassName(rs_stmt.m_rs);
  +        ClassDescriptor cld;
  +        
  +        if (ojbClass != null)
  +        {
  +            cld = m_cld.getRepository().getDescriptorFor(ojbClass);
  +        }
  +        else
  +        {
  +            cld = m_cld;
  +        }
  +
  +        FieldDescriptor[] pkFields = cld.getPkFields();
  +        readValuesFrom(rs_stmt, row, pkFields);
       }
   
  -    protected void readValuesFrom(ResultSet rs, Map row, FieldDescriptor[] fields)
  +    protected void readValuesFrom(ResultSetAndStatement rs_stmt, Map row, FieldDescriptor[] fields)
       {
           int size = fields.length;
           Object val = null;
  @@ -225,7 +252,8 @@
                   fld = fields[j];
                   if(!row.containsKey(fld.getColumnName()))
                   {
  -                    val = fld.getJdbcType().getObjectFromColumn(rs, fld.getColumnName());
  +                    int idx = rs_stmt.m_sql.getColumnIndex(fld);
  +                    val = fld.getJdbcType().getObjectFromColumn(rs_stmt.m_rs, null, fld.getColumnName(), idx);
                       row.put(fld.getColumnName(), fld.getFieldConversion().sqlToJava(val));
                   }
               }
  @@ -279,7 +307,7 @@
       protected ClassDescriptor selectClassDescriptor(Map row) throws PersistenceBrokerException
       {
           ClassDescriptor result = m_cld;
  -        String ojbConcreteClass = (String) row.get(OJB_CONCRETE_CLASS_KEY);
  +        Class ojbConcreteClass = (Class) row.get(OJB_CONCRETE_CLASS_KEY);
           if(ojbConcreteClass != null)
           {
               result = m_cld.getRepository().getDescriptorFor(ojbConcreteClass);
  
  
  
  1.22.2.7  +40 -16    db-ojb/src/java/org/apache/ojb/broker/accesslayer/JdbcAccessImpl.java
  
  Index: JdbcAccessImpl.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/accesslayer/JdbcAccessImpl.java,v
  retrieving revision 1.22.2.6
  retrieving revision 1.22.2.7
  diff -u -r1.22.2.6 -r1.22.2.7
  --- JdbcAccessImpl.java	4 Jun 2005 14:13:43 -0000	1.22.2.6
  +++ JdbcAccessImpl.java	5 Oct 2005 18:01:25 -0000	1.22.2.7
  @@ -29,10 +29,12 @@
   import org.apache.ojb.broker.PersistenceBroker;
   import org.apache.ojb.broker.PersistenceBrokerException;
   import org.apache.ojb.broker.PersistenceBrokerSQLException;
  +import org.apache.ojb.broker.accesslayer.sql.SelectStatement;
   import org.apache.ojb.broker.core.ValueContainer;
   import org.apache.ojb.broker.metadata.ArgumentDescriptor;
   import org.apache.ojb.broker.metadata.ClassDescriptor;
   import org.apache.ojb.broker.metadata.FieldDescriptor;
  +import org.apache.ojb.broker.metadata.JdbcType;
   import org.apache.ojb.broker.metadata.ProcedureDescriptor;
   import org.apache.ojb.broker.metadata.fieldaccess.PersistentField;
   import org.apache.ojb.broker.platforms.Platform;
  @@ -175,7 +177,7 @@
   
           try
           {
  -            final String sql = this.broker.serviceSqlGenerator().getPreparedDeleteStatement(query, cld);
  +            final String sql = this.broker.serviceSqlGenerator().getPreparedDeleteStatement(query, cld).getStatement();
               stmt = broker.serviceStatementManager().getPreparedStatement(cld, sql,
                       false, StatementManagerIF.FETCH_SIZE_NOT_APPLICABLE, cld.getDeleteProcedure()!=null);
   
  @@ -312,13 +314,15 @@
               scrollable = true;
           }
           ResultSetAndStatement retval = null;
  +        SelectStatement sql = null;
  +
           try
           {
               final int queryFetchSize = query.getFetchSize();
  -            final String sql = broker.serviceSqlGenerator().getPreparedSelectStatement(query, cld);
  -            final boolean isStoredProcedure = isStoredProcedure(sql);
  +            sql = broker.serviceSqlGenerator().getPreparedSelectStatement(query, cld);
  +            final boolean isStoredProcedure = isStoredProcedure(sql.getStatement());
               final PreparedStatement stmt;
  -            stmt = broker.serviceStatementManager().getPreparedStatement(cld, sql,
  +            stmt = broker.serviceStatementManager().getPreparedStatement(cld, sql.getStatement() ,
                       scrollable, queryFetchSize, isStoredProcedure);
   
               ResultSet rs;
  @@ -345,7 +349,7 @@
                   rs = stmt.executeQuery();
               }
   
  -            retval = new ResultSetAndStatement(getPlatform(), stmt, rs);
  +            retval = new ResultSetAndStatement(getPlatform(), stmt, rs, sql);
               return retval;
           }
           catch (PersistenceBrokerException e)
  @@ -394,23 +398,23 @@
   
       /**
        * performs a SQL SELECT statement against RDBMS.
  -     * @param sqlStatement the query string.
  +     * @param sql the query string.
        * @param cld ClassDescriptor providing meta-information.
        */
       public ResultSetAndStatement executeSQL(
  -        String sqlStatement,
  +        final String sql,
           ClassDescriptor cld,
           ValueContainer[] values,
           boolean scrollable)
           throws PersistenceBrokerException
       {
  -        if (logger.isDebugEnabled()) logger.debug("executeSQL: " + sqlStatement);
  -        final boolean isStoredprocedure = isStoredProcedure(sqlStatement);
  +        if (logger.isDebugEnabled()) logger.debug("executeSQL: " + sql);
  +        final boolean isStoredprocedure = isStoredProcedure(sql);
           StatementManagerIF stmtMan = broker.serviceStatementManager();
           ResultSetAndStatement retval = null;
           try
           {
  -            final PreparedStatement stmt = stmtMan.getPreparedStatement(cld, sqlStatement,
  +            final PreparedStatement stmt = stmtMan.getPreparedStatement(cld, sql,
                       scrollable, StatementManagerIF.FETCH_SIZE_NOT_EXPLICITLY_SET, isStoredprocedure);
   
               ResultSet rs;
  @@ -431,7 +435,23 @@
   
               // as we return the resultset for further operations, we cannot release the statement yet.
               // that has to be done by the JdbcAccess-clients (i.e. RsIterator, ProxyRsIterator and PkEnumeration.)
  -            retval = new ResultSetAndStatement(getPlatform(), stmt, rs);
  +            retval = new ResultSetAndStatement(getPlatform(), stmt, rs, new SelectStatement()
  +            {
  +                public Query getQueryInstance()
  +                {
  +                    return null;
  +                }
  +
  +                public int getColumnIndex(FieldDescriptor fld)
  +                {
  +                    return JdbcType.MIN_INT;
  +                }
  +
  +                public String getStatement()
  +                {
  +                    return sql;
  +                }
  +            });
               return retval;
           }
           catch (PersistenceBrokerException e)
  @@ -450,7 +470,7 @@
           }
           catch (SQLException e)
           {
  -            String msg = "SQLException during the execution of the SQL query: " + sqlStatement
  +            String msg = "SQLException during the execution of the SQL query: " + sql
                       + ", message is: " + e.getMessage();
               logger.error(msg, e);
               /**
  @@ -622,11 +642,13 @@
       public Object materializeObject(ClassDescriptor cld, Identity oid)
           throws PersistenceBrokerException
       {
  +        final StatementManagerIF sm = broker.serviceStatementManager();
           ResultSet rs = null;
           PreparedStatement stmt = null;
  +        SelectStatement sql = broker.serviceSqlGenerator().getPreparedSelectByPkStatement(cld);
           try
           {
  -            stmt = broker.serviceStatementManager().getSelectByPKStatement(cld);
  +            stmt = sm.getSelectByPKStatement(cld);
               if (stmt == null)
               {
                   logger.error("getSelectByPKStatement returned a null statement");
  @@ -636,14 +658,16 @@
               arminw: currently a select by PK could never be a stored procedure,
               thus we can always set 'false'. Is this correct??
               */
  -            broker.serviceStatementManager().bindSelect(stmt, oid, cld, false);
  +            sm.bindSelect(stmt, oid, cld, false);
               rs = stmt.executeQuery();
   
               // data available read object, else return null
               if (rs.next())
               {
                   Map row = new HashMap();
  -                cld.getRowReader().readObjectArrayFrom(rs, row);
  +                ResultSetAndStatement rs_stmt = new ResultSetAndStatement(getPlatform(), stmt, rs, sql);
  +
  +                cld.getRowReader().readObjectArrayFrom(rs_stmt, row);
                   return cld.getRowReader().readObjectFrom(row);
               }
               else
  
  
  
  1.22.2.6  +5 -5      db-ojb/src/java/org/apache/ojb/broker/accesslayer/Attic/StatementsForClassImpl.java
  
  Index: StatementsForClassImpl.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/accesslayer/Attic/StatementsForClassImpl.java,v
  retrieving revision 1.22.2.5
  retrieving revision 1.22.2.6
  diff -u -r1.22.2.5 -r1.22.2.6
  --- StatementsForClassImpl.java	4 Jun 2005 14:13:43 -0000	1.22.2.5
  +++ StatementsForClassImpl.java	5 Oct 2005 18:01:25 -0000	1.22.2.6
  @@ -104,7 +104,7 @@
       {
           if (deleteSql == null)
           {
  -            deleteSql = sqlGenerator.getPreparedDeleteStatement(classDescriptor);
  +            deleteSql = sqlGenerator.getPreparedDeleteStatement(classDescriptor).getStatement();
           }
           try
           {
  @@ -153,7 +153,7 @@
       {
           if (insertSql == null)
           {
  -            insertSql = sqlGenerator.getPreparedInsertStatement(classDescriptor);
  +            insertSql = sqlGenerator.getPreparedInsertStatement(classDescriptor).getStatement();
           }
           try
           {
  @@ -192,7 +192,7 @@
       {
           if (selectByPKSql == null)
           {
  -            selectByPKSql = sqlGenerator.getPreparedSelectByPkStatement(classDescriptor);
  +            selectByPKSql = sqlGenerator.getPreparedSelectByPkStatement(classDescriptor).getStatement();
           }
           try
           {
  @@ -220,7 +220,7 @@
       {
           if (updateSql == null)
           {
  -            updateSql = sqlGenerator.getPreparedUpdateStatement(classDescriptor);
  +            updateSql = sqlGenerator.getPreparedUpdateStatement(classDescriptor).getStatement();
           }
           try
           {
  
  
  
  1.9.2.1   +4 -4      db-ojb/src/java/org/apache/ojb/broker/accesslayer/RowReader.java
  
  Index: RowReader.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/accesslayer/RowReader.java,v
  retrieving revision 1.9
  retrieving revision 1.9.2.1
  diff -u -r1.9 -r1.9.2.1
  --- RowReader.java	4 Apr 2004 23:53:31 -0000	1.9
  +++ RowReader.java	5 Oct 2005 18:01:25 -0000	1.9.2.1
  @@ -28,7 +28,7 @@
   	static final long serialVersionUID = -1283322922537162249L;    /**
        * materialize a single object from the values of the Map row.
        * the implementor of this class must not care for materializing
  -     * references or collection attributes, this is done later!
  +     * references or collection attributes, this is done later! 
        * @param row the Map containing the new values
        * @return a properly created instance.
        */
  @@ -46,13 +46,13 @@
   	 * Read all fields from the current ResultRow into the Object[] row.#
   	 * ConversionStrategies are applied here!
   	 */
  -	public void readObjectArrayFrom(ResultSet rs, Map row);
  +	public void readObjectArrayFrom(ResultSetAndStatement rs, Map row);
   
   	/**
   	 * Read primary key fields from the current ResultRow into the Object[] row.#
   	 * ConversionStrategies are applied here!
   	 */
  -	public void readPkValuesFrom(ResultSet rs, Map row);
  +	public void readPkValuesFrom(ResultSetAndStatement rs, Map row);
   
       /**
        * Set the descriptor this <i>RowReader</i> worked with.
  
  
  
  1.13.2.1  +5 -2      db-ojb/src/java/org/apache/ojb/broker/accesslayer/ResultSetAndStatement.java
  
  Index: ResultSetAndStatement.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/accesslayer/ResultSetAndStatement.java,v
  retrieving revision 1.13
  retrieving revision 1.13.2.1
  diff -u -r1.13 -r1.13.2.1
  --- ResultSetAndStatement.java	22 May 2004 09:51:25 -0000	1.13
  +++ ResultSetAndStatement.java	5 Oct 2005 18:01:25 -0000	1.13.2.1
  @@ -15,6 +15,7 @@
    * limitations under the License.
    */
   
  +import org.apache.ojb.broker.accesslayer.sql.SelectStatement;
   import org.apache.ojb.broker.platforms.Platform;
   import org.apache.ojb.broker.platforms.PlatformException;
   import org.apache.ojb.broker.util.logging.Logger;
  @@ -41,12 +42,14 @@
       */
   	public final ResultSet m_rs;
   	public final Statement m_stmt;
  +    public final SelectStatement m_sql;
   
  -	public ResultSetAndStatement(Platform platform, Statement stmt, ResultSet rs)
  +	public ResultSetAndStatement(Platform platform, Statement stmt, ResultSet rs, SelectStatement sql)
   	{
   		m_platform = platform;
           m_stmt = stmt;
           m_rs = rs;
  +        m_sql = sql;
           isClosed = false;
   	}
   
  
  
  
  1.63.2.16 +7 -10     db-ojb/src/java/org/apache/ojb/broker/accesslayer/RsIterator.java
  
  Index: RsIterator.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/accesslayer/RsIterator.java,v
  retrieving revision 1.63.2.15
  retrieving revision 1.63.2.16
  diff -u -r1.63.2.15 -r1.63.2.16
  --- RsIterator.java	26 Aug 2005 19:26:39 -0000	1.63.2.15
  +++ RsIterator.java	5 Oct 2005 18:01:25 -0000	1.63.2.16
  @@ -78,7 +78,6 @@
   public class RsIterator implements OJBIterator
   {
       protected Logger logger = LoggerFactory.getLogger(this.getClass());
  -
       private static final String INFO_MSG = "Resources already cleaned up, recommend to set" +
               " this flag before first use of the iterator";
       /*
  @@ -86,7 +85,6 @@
   	 * and set the target object on every use TODO: Find a better solution
   	 */
       private PBLifeCycleEvent afterLookupEvent;
  -
       private MaterializationCache m_cache;
   
       /**
  @@ -149,7 +147,6 @@
        * done or not. Default is <tt>true</tt>.
        */
       private boolean autoRelease = true;
  -
       private ResourceWrapper resourceListener;
       
       /** if true do not fire PBLifeCycleEvent. */
  @@ -306,7 +303,6 @@
               autoReleaseDbResources();
               logger.error("Error while iterate ResultSet for query " + m_queryObject, ex);
               throw new NoSuchElementException("Could not obtain next object: " + ex.getMessage());
  -
           }
       }
   
  @@ -435,9 +431,10 @@
            * itemProxyClass should NOT be a member variable.
            */
   
  +        RowReader rowReader = getQueryObject().getClassDescriptor().getRowReader();
           // in any case we need the PK values of result set row
           // provide m_row with primary key data of current row
  -        getQueryObject().getClassDescriptor().getRowReader().readPkValuesFrom(getRsAndStmt().m_rs, getRow());
  +        rowReader.readPkValuesFrom(getRsAndStmt(), getRow());
   
           if (getItemProxyClass() != null)
           {
  @@ -456,10 +453,10 @@
               {
   
                   // map all field values from the current result set
  -                getQueryObject().getClassDescriptor().getRowReader().readObjectArrayFrom(getRsAndStmt().m_rs, getRow());
  +                rowReader.readObjectArrayFrom(getRsAndStmt(), getRow());
                   // 3. If Object is not in cache
                   // materialize Object with primitive attributes filled from current row
  -                result = getQueryObject().getClassDescriptor().getRowReader().readObjectFrom(getRow());
  +                result = rowReader.readObjectFrom(getRow());
                   // result may still be null!
                   if (result != null)
                   {
  @@ -507,8 +504,8 @@
                   if (cld.isAlwaysRefresh())
                   {
                       // map all field values from the current result set
  -                    getQueryObject().getClassDescriptor().getRowReader().readObjectArrayFrom(getRsAndStmt().m_rs, getRow());
  -                    getQueryObject().getClassDescriptor().getRowReader().refreshObject(result, getRow());
  +                    rowReader.readObjectArrayFrom(getRsAndStmt(), getRow());
  +                    rowReader.refreshObject(result, getRow());
                   }
                   getBroker().checkRefreshRelationships(result, oid, cld);
               }
  
  
  
  No                   revision
  No                   revision
  1.22.2.5  +168 -23   db-ojb/src/java/org/apache/ojb/broker/accesslayer/sql/SqlSelectStatement.java
  
  Index: SqlSelectStatement.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/accesslayer/sql/SqlSelectStatement.java,v
  retrieving revision 1.22.2.4
  retrieving revision 1.22.2.5
  diff -u -r1.22.2.4 -r1.22.2.5
  --- SqlSelectStatement.java	8 Jun 2005 19:45:30 -0000	1.22.2.4
  +++ SqlSelectStatement.java	5 Oct 2005 18:01:26 -0000	1.22.2.5
  @@ -19,14 +19,19 @@
   import java.util.Iterator;
   import java.util.List;
   import java.util.Map;
  +import java.util.Set;
   
  +import org.apache.commons.collections.set.ListOrderedSet;
   import org.apache.ojb.broker.metadata.ClassDescriptor;
  +import org.apache.ojb.broker.metadata.DescriptorRepository;
   import org.apache.ojb.broker.metadata.FieldDescriptor;
  +import org.apache.ojb.broker.metadata.JdbcType;
   import org.apache.ojb.broker.platforms.Platform;
   import org.apache.ojb.broker.query.Criteria;
   import org.apache.ojb.broker.query.Query;
   import org.apache.ojb.broker.query.ReportQuery;
   import org.apache.ojb.broker.query.ReportQueryByCriteria;
  +import org.apache.ojb.broker.util.SqlHelper;
   import org.apache.ojb.broker.util.logging.Logger;
   
   /**
  @@ -35,8 +40,9 @@
    * @author <a href="mailto:jbraeuchi@hotmail.com">Jakob Braeuchi</a>
    * @version $Id$
    */
  -public class SqlSelectStatement extends SqlQueryStatement
  +public class SqlSelectStatement extends SqlQueryStatement implements SelectStatement
   {
  +    private FieldDescriptor[] fieldsForSelect;
   
       /**
        * Constructor for SqlSelectStatement.
  @@ -66,12 +72,21 @@
       }
   
       /**
  +     * Append a Column with alias: A0 name -> A0.name
  +     * @param anAlias the TableAlias
  +     * @param aColumn name
  +     * @param buf
  +     */
  +    protected void appendColumn(TableAlias anAlias, FieldDescriptor field, StringBuffer buf)
  +    {
  +        buf.append(anAlias.alias);
  +        buf.append(".");
  +        buf.append(field.getColumnName());
  +    }
  +
  +    /**
        * Appends to the statement a comma separated list of column names.
        *
  -     * MBAIRD: if the object being queried on has multiple classes mapped to the table,
  -     * then we will get all the fields that are a unique set across all those classes so if we need to
  -     * we can materialize an extent
  -     *
        * DO NOT use this if order of columns is important. The row readers build reflectively and look up
        * column names to find values, so this is safe. In the case of update, you CANNOT use this as the
        * order of columns is important.
  @@ -81,29 +96,140 @@
        */
       protected List appendListOfColumnsForSelect(ClassDescriptor cld, StringBuffer buf)
       {
  -        FieldDescriptor[] fieldDescriptors = cld.getRepository().getFieldDescriptorsForMultiMappedTable(cld);
  -        int fieldDescriptorLength = fieldDescriptors.length;
  +        FieldDescriptor[] fieldDescriptors = getFieldsForSelect(cld);
           ArrayList columnList = new ArrayList();
  -        int i = 0;
  +        TableAlias searchAlias = getSearchTable();
  +        
  +        for (int i = 0; i < fieldDescriptors.length; i++)
  +        {
  +            FieldDescriptor field = fieldDescriptors[i];
  +            TableAlias alias = getTableAliasForClassDescriptor(field.getClassDescriptor());
  +            if (alias == null)
  +            {
  +                alias = searchAlias;
  +            }
  +            if (i > 0)
  +            {
  +                buf.append(",");
  +            }
  +            appendColumn(alias, field, buf);
  +            columnList.add(field.getAttributeName());
  +        }
  +        
  +        appendClazzColumnForSelect(cld, buf);
  +        return columnList;
  +    }
  + 
  +    /**
  +     * Create the OJB_CLAZZ pseudo column. This column defines the Class to be instantiated
  +     * @param cld
  +     * @param buf
  +     */
  +    private void appendClazzColumnForSelect(ClassDescriptor cld, StringBuffer buf)
  +    {
  +        DescriptorRepository repository = cld.getRepository();
  +        Class[] multiJoinedClasses = repository.getSubClassesMultipleJoinedTables(cld, true);
  +
  +        if (multiJoinedClasses.length == 0)
  +        {
  +            return;
  +        }
  +        
  +        buf.append(",CASE");
   
  -        if (fieldDescriptors != null)
  +        for (int i = multiJoinedClasses.length; i > 0; i--)
           {
  -            FieldDescriptor field = null;
  -            for (int j = 0; j < fieldDescriptorLength; j++)
  +            buf.append(" WHEN ");
  +
  +            ClassDescriptor subCld = repository.getDescriptorFor(multiJoinedClasses[i-1]);
  +            FieldDescriptor[] fieldDescriptors = subCld.getPkFields();
  +
  +            TableAlias alias = getTableAliasForClassDescriptor(subCld);
  +            for (int j = 0; j < fieldDescriptors.length; j++)
               {
  -                field = fieldDescriptors[j];
  -                if (i > 0)
  +                FieldDescriptor field = fieldDescriptors[j];
  +                if (j > 0)
                   {
  -                    buf.append(",");
  +                    buf.append(" AND ");
                   }
  -                buf.append(getSearchTable().alias);
  -                buf.append(".");
  -                buf.append(field.getColumnName());
  -                columnList.add(field.getAttributeName());
  -                i++;
  +                appendColumn(alias, field, buf);
  +                buf.append(" IS NOT NULL");
               }
  +            buf.append(" THEN '" + subCld.getClassNameOfObject() + "'");
           }
  -        return columnList;
  +        buf.append(" ELSE '" + cld.getClassNameOfObject() + "'");
  +        buf.append(" END AS " + SqlHelper.OJB_CLASS_COLUMN);
  +    }
  +    
  +    /**
  +     * Return the Fields to be selected.
  +     *
  +     * @param cld the ClassDescriptor
  +     * @return the Fields to be selected
  +     */
  +    protected FieldDescriptor[] buildFieldsForSelect(ClassDescriptor cld)
  +    {
  +        DescriptorRepository repository = cld.getRepository();
  +        Set fields = new ListOrderedSet();   // keep the order of the fields
  +        
  +        // add Standard Fields
  +        // MBAIRD: if the object being queried on has multiple classes mapped to the table,
  +        // then we will get all the fields that are a unique set across all those classes so if we need to
  +        // we can materialize an extent
  +        FieldDescriptor fds[] = repository.getFieldDescriptorsForMultiMappedTable(cld);
  +        for (int i = 0; i < fds.length; i++)
  +        {
  +            fields.add(fds[i]);
  +        }
  +
  +        // add inherited Fields. This is important when querying for a class having a super-reference
  +        fds = cld.getFieldDescriptor(true);
  +        for (int i = 0; i < fds.length; i++)
  +        {
  +            fields.add(fds[i]);
  +        }
  +
  +        // add Fields of joined subclasses
  +        Class[] multiJoinedClasses = repository.getSubClassesMultipleJoinedTables(cld, true);
  +        for (int c = 0; c < multiJoinedClasses.length; c++)
  +        {
  +            ClassDescriptor subCld = repository.getDescriptorFor(multiJoinedClasses[c]);
  +            fds = subCld.getFieldDescriptions();
  +            for (int i = 0; i < fds.length; i++)
  +            {
  +                fields.add(fds[i]);
  +            }
  +        }
  +
  +        FieldDescriptor[] result = new FieldDescriptor[fields.size()];
  +        fields.toArray(result);
  +        return result;
  +    }
  +
  +    /**
  +     * Return the Fields to be selected.
  +     *
  +     * @return the Fields to be selected
  +     */
  +    FieldDescriptor[] getFieldsForSelect()
  +    {
  +        return getFieldsForSelect(getSearchClassDescriptor());
  +    }
  +
  +    /**
  +     * Return the Fields to be selected.
  +     *
  +     * @param cld the ClassDescriptor
  +     * @return the Fields to be selected
  +     */
  +    protected FieldDescriptor[] getFieldsForSelect(ClassDescriptor cld)
  +    {
  +        if (fieldsForSelect == null)
  +        {
  +            fieldsForSelect = buildFieldsForSelect(cld);
  +        }
  +
  +        return fieldsForSelect;
       }
   
       /**
  @@ -297,10 +423,29 @@
               buf.append(cldSuper.getFullTableName());
               buf.append(".");
               buf.append(field.getColumnName());
  -            //columnList.add(field.getAttributeName());
  -
           }
  +    }
   
  +    public Query getQueryInstance()
  +    {
  +        return getQuery();
  +    }
  +
  +    public int getColumnIndex(FieldDescriptor fld)
  +    {
  +        int index = JdbcType.MIN_INT;
  +        if (fieldsForSelect != null)
  +        {
  +            for (int i = 0; i < fieldsForSelect.length; i++)
  +            {
  +                if (fieldsForSelect[i].equals(fld))
  +                {
  +                    index = i + 1;  // starts at 1
  +                    break;
  +                }
  +            }
  +        }
  +        return index;
       }
   
   }
  
  
  
  1.8.2.1   +18 -63    db-ojb/src/java/org/apache/ojb/broker/accesslayer/sql/SqlSelectByPkStatement.java
  
  Index: SqlSelectByPkStatement.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/accesslayer/sql/SqlSelectByPkStatement.java,v
  retrieving revision 1.8
  retrieving revision 1.8.2.1
  diff -u -r1.8 -r1.8.2.1
  --- SqlSelectByPkStatement.java	4 Apr 2004 23:53:32 -0000	1.8
  +++ SqlSelectByPkStatement.java	5 Oct 2005 18:01:26 -0000	1.8.2.1
  @@ -15,88 +15,43 @@
    * limitations under the License.
    */
   
  -import java.util.ArrayList;
  -import java.util.List;
  -
   import org.apache.ojb.broker.metadata.ClassDescriptor;
   import org.apache.ojb.broker.metadata.FieldDescriptor;
  +import org.apache.ojb.broker.platforms.Platform;
  +import org.apache.ojb.broker.query.Criteria;
  +import org.apache.ojb.broker.query.Query;
  +import org.apache.ojb.broker.query.QueryByCriteria;
   import org.apache.ojb.broker.util.logging.Logger;
   
   /**
    * Model a SELECT Statement by Primary Key
    * 
  - * @author <a href="mailto:jbraeuchi@hotmail.com">Jakob Braeuchi</a>
  + * @author <a href="mailto:jbraeuchi@gmx.ch">Jakob Braeuchi</a>
    * @version $Id$
    */
   
  -public class SqlSelectByPkStatement extends SqlPkStatement
  +public class SqlSelectByPkStatement extends SqlSelectStatement
   {
  -
   	/**
   	 * Constructor for SqlSelectByPkStatement.
   	 * @param cld
   	 * @param logger
   	 */
  -	public SqlSelectByPkStatement(ClassDescriptor cld, Logger logger)
  -	{
  -		super(cld, logger);
  +	public SqlSelectByPkStatement(Platform pf, ClassDescriptor cld, Logger logger)
  +	{        
  +        super(pf, cld, buildQuery(cld), logger);
   	}
   
  -    /**
  -     * Appends to the statement a comma separated list of column names.
  -     *
  -     * MBAIRD: if the object being queried on has multiple classes mapped to the table,
  -     * then we will get all the fields that are a unique set across all those classes so if we need to
  -     * we can materialize an extent
  -     *
  -     * DO NOT use this if order of columns is important. The row readers build reflectively and look up
  -     * column names to find values, so this is safe. In the case of update, you CANNOT use this as the
  -     * order of columns is important.
  -     *
  -     * @return list of column names for the set of all unique columns for multiple classes mapped to the
  -     * same table.
  -     */
  -	protected List appendListOfColumnsForSelect(ClassDescriptor cld, StringBuffer buf)
  +    private static Query buildQuery(ClassDescriptor cld)
       {
  -        FieldDescriptor[] fieldDescriptors = cld.getRepository().getFieldDescriptorsForMultiMappedTable(cld);
  -        ArrayList columnList = new ArrayList();
  -
  -        if (fieldDescriptors != null)
  +        FieldDescriptor[] pkFields = cld.getPkFields();
  +        Criteria crit = new Criteria();
  +        
  +        for (int i = 0; i < pkFields.length; i++)
           {
  -            int i = 0;
  -            int fieldDescriptorLength = fieldDescriptors.length;
  -            FieldDescriptor field = null;
  -            
  -            for (int j = 0; j < fieldDescriptorLength; j++)
  -            {
  -                field = fieldDescriptors[j];
  -                if (i > 0)
  -                {
  -                    buf.append(",");
  -                }
  -                buf.append(field.getColumnName());
  -                columnList.add(field.getAttributeName());
  -                i++;
  -            }
  +            crit.addEqualTo(pkFields[i].getAttributeName(), null);
           }
  -        return columnList;
  -    }
  -
  -	/**
  -     * Answer the SELECT by primary key Sql for the Statement
  -     */
  -    public String getStatement()
  -    {
  -        StringBuffer stmt = new StringBuffer(1024);
  -        ClassDescriptor cld = getClassDescriptor();
  - 		
  -        stmt.append("SELECT ");
  - 		appendListOfColumnsForSelect(cld, stmt);
  -        stmt.append(" FROM ");
  -        appendTable(cld, stmt);
  -        appendWhereClause(cld, false, stmt);
  -        
  -        return stmt.toString();
  +        Query query = new QueryByCriteria(cld.getClassOfObject(), crit);        
  +        return query;
       }
  -
   }
  
  
  
  1.75.2.10 +50 -4     db-ojb/src/java/org/apache/ojb/broker/accesslayer/sql/SqlQueryStatement.java
  
  Index: SqlQueryStatement.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/accesslayer/sql/SqlQueryStatement.java,v
  retrieving revision 1.75.2.9
  retrieving revision 1.75.2.10
  diff -u -r1.75.2.9 -r1.75.2.10
  --- SqlQueryStatement.java	14 Aug 2005 16:00:33 -0000	1.75.2.9
  +++ SqlQueryStatement.java	5 Oct 2005 18:01:26 -0000	1.75.2.10
  @@ -138,6 +138,8 @@
           // Walk the super reference-descriptor
           buildSuperJoinTree(m_root, m_baseCld, "" ,false);
   
  +        buildMultiJoinTree(m_root, m_baseCld, "", true);
  +
           // In some cases it is necessary to split the query criteria
           // and then to generate UNION of several SELECTs
           // We build the joinTreeToCriteria mapping,
  @@ -1329,11 +1331,22 @@
       /**
        * Answer the TableAlias for ClassDescriptor.
        */
  -    private TableAlias getTableAliasForClassDescriptor(ClassDescriptor aCld)
  +    protected TableAlias getTableAliasForClassDescriptor(ClassDescriptor aCld)
       {
           return (TableAlias) m_cldToAlias.get(aCld);
       }
  -    
  +
  +    /**
  +     * Set the TableAlias for ClassDescriptor
  +     */
  +    private void setTableAliasForClassDescriptor(ClassDescriptor aCld, TableAlias anAlias)
  +    {
  +        if (m_cldToAlias.get(aCld) == null)
  +        {
  +            m_cldToAlias.put(aCld, anAlias);
  +        }    
  +    }
  +
       /**
        * Answer the TableAlias for aPath or aUserAlias
        * @param aPath
  @@ -1652,6 +1665,39 @@
       }
   
       /**
  +     * build the Join-Information for Subclasses having a super reference to this class
  +     *
  +     * @param left
  +     * @param cld
  +     * @param name
  +     */
  +    private void buildMultiJoinTree(TableAlias left, ClassDescriptor cld, String name, boolean useOuterJoin)
  +    {
  +        DescriptorRepository repository = cld.getRepository();
  +        Class[] multiJoinedClasses = repository.getSubClassesMultipleJoinedTables(cld, false);
  +
  +        for (int i = 0; i < multiJoinedClasses.length; i++)
  +        {
  +            ClassDescriptor subCld = repository.getDescriptorFor(multiJoinedClasses[i]);
  +            SuperReferenceDescriptor srd = subCld.getSuperReference();
  +            if (srd != null)
  +            {
  +                FieldDescriptor[] leftFields = subCld.getPkFields();
  +                FieldDescriptor[] rightFields = srd.getForeignKeyFieldDescriptors(subCld);
  +                TableAlias base_alias = getTableAliasForPath(name, null);
  +
  +                String aliasName = String.valueOf(getAliasChar()) + m_aliasCount++;
  +                TableAlias right = new TableAlias(subCld, aliasName, false, null);
  +
  +                Join join1to1 = new Join(left, leftFields, right, rightFields, useOuterJoin, "subClass");
  +                base_alias.addJoin(join1to1);
  +
  +                buildMultiJoinTree(right, subCld, name, useOuterJoin);
  +            }
  +        }
  +    }
  +
  +    /**
        * First reduce the Criteria to the normal disjunctive form, then
        * calculate the necessary tree of joined tables for each item, then group
        * items with the same tree of joined tables.
  @@ -1789,7 +1835,7 @@
               boolean useHintsOnExtents = false;
   
               // BRJ: store alias map of in enclosing class
  -			SqlQueryStatement.this.m_cldToAlias.put(aCld, this);
  +			setTableAliasForClassDescriptor(aCld, this);
   			
               //LEANDRO: use hints
               if (hints != null && hints.size() > 0)
  
  
  
  1.8.2.1   +8 -8      db-ojb/src/java/org/apache/ojb/broker/accesslayer/sql/SqlGenerator.java
  
  Index: SqlGenerator.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/accesslayer/sql/SqlGenerator.java,v
  retrieving revision 1.8
  retrieving revision 1.8.2.1
  diff -u -r1.8 -r1.8.2.1
  --- SqlGenerator.java	4 Apr 2004 23:53:32 -0000	1.8
  +++ SqlGenerator.java	5 Oct 2005 18:01:26 -0000	1.8.2.1
  @@ -61,49 +61,49 @@
        * @param query the Query
        * @param cld the ClassDescriptor
        */
  -    public String getPreparedSelectStatement(Query query, ClassDescriptor cld);
  +    public SelectStatement getPreparedSelectStatement(Query query, ClassDescriptor cld);
   
       /**
        * generate a select-Statement according to query
        * @param query the Query
        * @param cld the ClassDescriptor
        */
  -    public String getSelectStatementDep(Query query, ClassDescriptor cld);
  +    public SelectStatement getSelectStatementDep(Query query, ClassDescriptor cld);
   
       /**
        * generate a prepared DELETE-Statement according to query
        * @param query the Query
        * @param cld the ClassDescriptor
        */
  -    public String getPreparedDeleteStatement(Query query, ClassDescriptor cld);
  +    public SqlStatement getPreparedDeleteStatement(Query query, ClassDescriptor cld);
       
       /**
        * generate a prepared DELETE-Statement for the Class
        * described by cld.
        * @param cld the ClassDescriptor
        */
  -    public String getPreparedDeleteStatement(ClassDescriptor cld);
  +    public SqlStatement getPreparedDeleteStatement(ClassDescriptor cld);
       
       /**
        * generate a prepared INSERT-Statement for the Class
        * described by mif.
        * @param cld the ClassDescriptor
        */
  -    public String getPreparedInsertStatement(ClassDescriptor cld);
  +    public SqlStatement getPreparedInsertStatement(ClassDescriptor cld);
       
       /**
        * generate a prepared SELECT-Statement for the Class
        * described by cld
        * @param cld the ClassDescriptor
        */
  -    public String getPreparedSelectByPkStatement(ClassDescriptor cld);
  +    public SelectStatement getPreparedSelectByPkStatement(ClassDescriptor cld);
   
       /**
        * generate a prepared UPDATE-Statement for the Class
        * described by cld
        * @param cld the ClassDescriptor
        */
  -    public String getPreparedUpdateStatement(ClassDescriptor cld);
  +    public SqlStatement getPreparedUpdateStatement(ClassDescriptor cld);
   
   
       /**
  
  
  
  1.23.2.2  +189 -93   db-ojb/src/java/org/apache/ojb/broker/accesslayer/sql/SqlGeneratorDefaultImpl.java
  
  Index: SqlGeneratorDefaultImpl.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/accesslayer/sql/SqlGeneratorDefaultImpl.java,v
  retrieving revision 1.23.2.1
  retrieving revision 1.23.2.2
  diff -u -r1.23.2.1 -r1.23.2.2
  --- SqlGeneratorDefaultImpl.java	13 Jan 2005 19:20:03 -0000	1.23.2.1
  +++ SqlGeneratorDefaultImpl.java	5 Oct 2005 18:01:26 -0000	1.23.2.2
  @@ -17,6 +17,7 @@
   
   import java.util.Collection;
   import java.util.Enumeration;
  +import java.util.HashMap;
   import java.util.Map;
   import java.util.WeakHashMap;
   
  @@ -48,7 +49,9 @@
   {
       private Logger logger = LoggerFactory.getLogger(SqlGeneratorDefaultImpl.class);
   
  -    private Map m_sqlCacheMap = new WeakHashMap();
  +    /** Cache for {@link SqlForClass} instances, keyed per class descriptor. */
  +    private HashMap sqlForClass = new HashMap();
  +    private HashMap m_sqlCacheMap = new HashMap();
       private Platform m_platform;
   
       /**
  @@ -65,27 +68,32 @@
        * described by cld.
        * @param cld the ClassDescriptor
        */
  -    public String getPreparedDeleteStatement(ClassDescriptor cld)
  +    public SqlStatement getPreparedDeleteStatement(ClassDescriptor cld)
       {
           SqlStatement sql;
  -        String result;
  -        ProcedureDescriptor pd = cld.getDeleteProcedure();
  -
  -        if (pd == null)
  -        {
  -            sql = new SqlDeleteByPkStatement(cld, logger);
  -        }
  -        else
  +        SqlForClass sfc = getSqlForClass(cld);
  +        sql = sfc.getDeleteSql();
  +        if(sql == null)
           {
  -            sql = new SqlProcedureStatement(pd, logger);
  -        }
  -        result = sql.getStatement();
  +            ProcedureDescriptor pd = cld.getDeleteProcedure();
   
  -        if (logger.isDebugEnabled())
  -        {
  -            logger.debug("SQL:" + result);
  +            if(pd == null)
  +            {
  +                sql = new SqlDeleteByPkStatement(cld, logger);
  +            }
  +            else
  +            {
  +                sql = new SqlProcedureStatement(pd, logger);
  +            }
  +            // set the sql string
  +            sfc.setDeleteSql(sql);
  +
  +            if(logger.isDebugEnabled())
  +            {
  +                logger.debug("SQL:" + sql.getStatement());
  +            }
           }
  -        return result;
  +        return sql;
       }
   
       /**
  @@ -93,27 +101,32 @@
        * described by cld.
        * @param cld the ClassDescriptor
        */
  -    public String getPreparedInsertStatement(ClassDescriptor cld)
  +    public SqlStatement getPreparedInsertStatement(ClassDescriptor cld)
       {
           SqlStatement sql;
  -        String result;
  -        ProcedureDescriptor pd = cld.getInsertProcedure();
  -
  -        if (pd == null)
  -        {
  -            sql = new SqlInsertStatement(cld, logger);
  -        }
  -        else
  +        SqlForClass sfc = getSqlForClass(cld);
  +        sql = sfc.getInsertSql();
  +        if(sql == null)
           {
  -            sql = new SqlProcedureStatement(pd, logger);
  -        }
  -        result = sql.getStatement();
  +            ProcedureDescriptor pd = cld.getInsertProcedure();
   
  -        if (logger.isDebugEnabled())
  -        {
  -            logger.debug("SQL:" + result);
  +            if(pd == null)
  +            {
  +                sql = new SqlInsertStatement(cld, logger);
  +            }
  +            else
  +            {
  +                sql = new SqlProcedureStatement(pd, logger);
  +            }
  +            // set the sql string
  +            sfc.setInsertSql(sql);
  +
  +            if(logger.isDebugEnabled())
  +            {
  +                logger.debug("SQL:" + sql.getStatement());
  +            }
           }
  -        return result;
  +        return sql;
       }
   
       /**
  @@ -121,19 +134,15 @@
        * described by cld
        * @param cld the ClassDescriptor
        */
  -    public String getPreparedSelectByPkStatement(ClassDescriptor cld)
  +    public SelectStatement getPreparedSelectByPkStatement(ClassDescriptor cld)
       {
  -        SqlStatement sql;
  -        String result;
  -
  -        sql = new SqlSelectByPkStatement(cld, logger);
  -        result = sql.getStatement();
  -
  +        SelectStatement sql = new SqlSelectByPkStatement(m_platform, cld, logger);
  +     
           if (logger.isDebugEnabled())
           {
  -            logger.debug("SQL:" + result);
  +            logger.debug("SQL:" + sql.getStatement());
           }
  -        return result;
  +        return sql;
       }
   
       /**
  @@ -141,21 +150,20 @@
        * @param query the Query
        * @param cld the ClassDescriptor
        */
  -    public String getPreparedSelectStatement(Query query, ClassDescriptor cld)
  -    {
  +    public SelectStatement getPreparedSelectStatement(Query query, ClassDescriptor cld)
  +    {     
           SqlCacheKey key = new SqlCacheKey(query, cld, SqlCacheKey.TYPE_SELECT);
  -        String result = (String) m_sqlCacheMap.get(key);
  -        if (result == null)
  +        SelectStatement sql = (SelectStatement) m_sqlCacheMap.get(key);
  +        if (sql == null)
           {
  -            SqlStatement sql = new SqlSelectStatement(m_platform, cld, query, logger);
  -            result = sql.getStatement();
  +            sql = new SqlSelectStatement(m_platform, cld, query, logger);
               if (logger.isDebugEnabled())
               {
  -                logger.debug("SQL:" + result);
  +                logger.debug("SQL:" + sql.getStatement());
               }
  -            m_sqlCacheMap.put(key, result);
  +            m_sqlCacheMap.put(key, sql);
           }
  -        return result;
  +        return sql;
       }
   
       /**
  @@ -163,25 +171,29 @@
        * described by cld
        * @param cld the ClassDescriptor
        */
  -    public String getPreparedUpdateStatement(ClassDescriptor cld)
  +    public SqlStatement getPreparedUpdateStatement(ClassDescriptor cld)
       {
  -        SqlStatement sql;
  -        String result;
  -        ProcedureDescriptor pd = cld.getUpdateProcedure();
  -
  -        if (pd == null)
  -        {
  -            sql = new SqlUpdateStatement(cld, logger);
  -        }
  -        else
  +        SqlForClass sfc = getSqlForClass(cld);
  +        SqlStatement result = sfc.getUpdateSql();
  +        if(result == null)
           {
  -            sql = new SqlProcedureStatement(pd, logger);
  -        }
  -        result = sql.getStatement();
  +            ProcedureDescriptor pd = cld.getUpdateProcedure();
   
  -        if (logger.isDebugEnabled())
  -        {
  -            logger.debug("SQL:" + result);
  +            if(pd == null)
  +            {
  +                result = new SqlUpdateStatement(cld, logger);
  +            }
  +            else
  +            {
  +                result = new SqlProcedureStatement(pd, logger);
  +            }
  +            // set the sql string
  +            sfc.setUpdateSql(result);
  +
  +            if(logger.isDebugEnabled())
  +            {
  +                logger.debug("SQL:" + result.getStatement());
  +            }
           }
           return result;
       }
  @@ -273,21 +285,20 @@
        * @param query the Query
        * @param cld the ClassDescriptor
        */
  -    public String getSelectStatementDep(Query query, ClassDescriptor cld)
  +    public SelectStatement getSelectStatementDep(Query query, ClassDescriptor cld)
       {
           SqlCacheKey key = new SqlCacheKey(query, cld, SqlCacheKey.TYPE_SELECT);
  -        String result = (String) m_sqlCacheMap.get(key);
  -        if (result == null)
  +        SelectStatement sql = (SelectStatement) m_sqlCacheMap.get(key);
  +        if (sql == null)
           {
  -            SqlStatement sql = new SqlSelectStatement(m_platform, cld, query, logger);
  -            result = sql.getStatement();
  +            sql = new SqlSelectStatement(m_platform, cld, query, logger);
               if (logger.isDebugEnabled())
               {
  -                logger.debug("SQL:" + result);
  +                logger.debug("SQL:" + sql.getStatement());
               }
  -            m_sqlCacheMap.put(key, result);
  +            m_sqlCacheMap.put(key, sql);
           }
  -        return result;
  +        return sql;
   
       }
   
  @@ -397,8 +408,9 @@
           
           if (attributeOrQuery instanceof Query)
           {
  -            Query q = (Query)attributeOrQuery;
  -            result = getPreparedSelectStatement(q,cld.getRepository().getDescriptorFor(q.getSearchClass()));
  +            Query q = (Query) attributeOrQuery;
  +            result = getPreparedSelectStatement(q, cld.getRepository().getDescriptorFor(q.getSearchClass()))
  +                    .getStatement();
           }   
           else
           {
  @@ -528,22 +540,9 @@
        * @param query the Query
        * @param cld the ClassDescriptor
        */
  -    public String getPreparedDeleteStatement(Query query, ClassDescriptor cld)
  +    public SqlStatement getPreparedDeleteStatement(Query query, ClassDescriptor cld)
       {
  -        SqlCacheKey key = new SqlCacheKey(query, cld, SqlCacheKey.TYPE_DELETE);
  -        String result = (String) m_sqlCacheMap.get(key);
  -        if (result == null)
  -        {
  -            SqlStatement sql;
  -            sql = new SqlDeleteByQuery(m_platform, cld, query, logger);
  -            result = sql.getStatement();
  -            m_sqlCacheMap.put(key, result);
  -            if (logger.isDebugEnabled())
  -            {
  -                logger.debug("SQL:" + result);
  -            }
  -        }
  -        return result;
  +        return new SqlDeleteByQuery(m_platform, cld, query, logger);
       }
   
       /* (non-Javadoc)
  @@ -554,4 +553,101 @@
           return m_platform;
       }
   
  +    /**
  +     * Returns the {@link SqlForClass} instance for
  +     * the given class descriptor.
  +     *
  +     * @param cld The class descriptor.
  +     * @return The {@link SqlForClass}.
  +     */
  +    protected SqlForClass getSqlForClass(ClassDescriptor cld)
  +    {
  +        SqlForClass result = (SqlForClass) sqlForClass.get(cld);
  +        if(result == null)
  +        {
  +            result = newInstanceSqlForClass();
  +            sqlForClass.put(cld, result);
  +        }
  +        return result;
  +    }
  +
  +    /**
  +     * User who want to extend this implementation can override this method to use
  +     * their own (extended) version of
  +     * {@link org.apache.ojb.broker.accesslayer.sql.SqlGeneratorDefaultImpl.SqlForClass}.
  +     *
  +     * @return A new instance.
  +     */
  +    protected SqlForClass newInstanceSqlForClass()
  +    {
  +        return new SqlForClass();
  +    }
  +
  +    //===================================================================
  +    // inner class
  +    //===================================================================
  +
  +    /**
  +     * This class serves as a cache for sql-Statements
  +     * used for persistence operations.
  +     */
  +    public static class SqlForClass
  +    {
  +        private SqlStatement deleteSql;
  +        private SqlStatement insertSql;
  +        private SqlStatement updateSql;
  +        private SelectStatement selectByPKSql;
  +        private SqlStatement selectExists;
  +
  +        public SqlStatement getDeleteSql()
  +        {
  +            return deleteSql;
  +        }
  +
  +        public void setDeleteSql(SqlStatement deleteSql)
  +        {
  +            this.deleteSql = deleteSql;
  +        }
  +
  +        public SqlStatement getInsertSql()
  +        {
  +            return insertSql;
  +        }
  +
  +        public void setInsertSql(SqlStatement insertSql)
  +        {
  +            this.insertSql = insertSql;
  +        }
  +
  +        public SqlStatement getUpdateSql()
  +        {
  +            return updateSql;
  +        }
  +
  +        public void setUpdateSql(SqlStatement updateSql)
  +        {
  +            this.updateSql = updateSql;
  +        }
  +
  +        public SelectStatement getSelectByPKSql()
  +        {
  +            return selectByPKSql;
  +        }
  +
  +        public void setSelectByPKSql(SelectStatement selectByPKSql)
  +        {
  +            this.selectByPKSql = selectByPKSql;
  +        }
  +
  +        public SqlStatement getSelectExists()
  +        {
  +            return selectExists;
  +        }
  +
  +        public void setSelectExists(SqlStatement selectExists)
  +        {
  +            this.selectExists = selectExists;
  +        }
  +    }
  +
   }
  
  
  
  No                   revision
  
  Index: SqlGeneratorDefaultImpl.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/accesslayer/sql/SqlGeneratorDefaultImpl.java,v
  retrieving revision 1.23.2.1
  retrieving revision 1.23.2.2
  diff -u -r1.23.2.1 -r1.23.2.2
  --- SqlGeneratorDefaultImpl.java	13 Jan 2005 19:20:03 -0000	1.23.2.1
  +++ SqlGeneratorDefaultImpl.java	5 Oct 2005 18:01:26 -0000	1.23.2.2
  @@ -17,6 +17,7 @@
   
   import java.util.Collection;
   import java.util.Enumeration;
  +import java.util.HashMap;
   import java.util.Map;
   import java.util.WeakHashMap;
   
  @@ -48,7 +49,9 @@
   {
       private Logger logger = LoggerFactory.getLogger(SqlGeneratorDefaultImpl.class);
   
  -    private Map m_sqlCacheMap = new WeakHashMap();
  +    /** Cache for {@link SqlForClass} instances, keyed per class descriptor. */
  +    private HashMap sqlForClass = new HashMap();
  +    private HashMap m_sqlCacheMap = new HashMap();
       private Platform m_platform;
   
       /**
  @@ -65,27 +68,32 @@
        * described by cld.
        * @param cld the ClassDescriptor
        */
  -    public String getPreparedDeleteStatement(ClassDescriptor cld)
  +    public SqlStatement getPreparedDeleteStatement(ClassDescriptor cld)
       {
           SqlStatement sql;
  -        String result;
  -        ProcedureDescriptor pd = cld.getDeleteProcedure();
  -
  -        if (pd == null)
  -        {
  -            sql = new SqlDeleteByPkStatement(cld, logger);
  -        }
  -        else
  +        SqlForClass sfc = getSqlForClass(cld);
  +        sql = sfc.getDeleteSql();
  +        if(sql == null)
           {
  -            sql = new SqlProcedureStatement(pd, logger);
  -        }
  -        result = sql.getStatement();
  +            ProcedureDescriptor pd = cld.getDeleteProcedure();
   
  -        if (logger.isDebugEnabled())
  -        {
  -            logger.debug("SQL:" + result);
  +            if(pd == null)
  +            {
  +                sql = new SqlDeleteByPkStatement(cld, logger);
  +            }
  +            else
  +            {
  +                sql = new SqlProcedureStatement(pd, logger);
  +            }
  +            // set the sql string
  +            sfc.setDeleteSql(sql);
  +
  +            if(logger.isDebugEnabled())
  +            {
  +                logger.debug("SQL:" + sql.getStatement());
  +            }
           }
  -        return result;
  +        return sql;
       }
   
       /**
  @@ -93,27 +101,32 @@
        * described by cld.
        * @param cld the ClassDescriptor
        */
  -    public String getPreparedInsertStatement(ClassDescriptor cld)
  +    public SqlStatement getPreparedInsertStatement(ClassDescriptor cld)
       {
           SqlStatement sql;
  -        String result;
  -        ProcedureDescriptor pd = cld.getInsertProcedure();
  -
  -        if (pd == null)
  -        {
  -            sql = new SqlInsertStatement(cld, logger);
  -        }
  -        else
  +        SqlForClass sfc = getSqlForClass(cld);
  +        sql = sfc.getInsertSql();
  +        if(sql == null)
           {
  -            sql = new SqlProcedureStatement(pd, logger);
  -        }
  -        result = sql.getStatement();
  +            ProcedureDescriptor pd = cld.getInsertProcedure();
   
  -        if (logger.isDebugEnabled())
  -        {
  -            logger.debug("SQL:" + result);
  +            if(pd == null)
  +            {
  +                sql = new SqlInsertStatement(cld, logger);
  +            }
  +            else
  +            {
  +                sql = new SqlProcedureStatement(pd, logger);
  +            }
  +            // set the sql string
  +            sfc.setInsertSql(sql);
  +
  +            if(logger.isDebugEnabled())
  +            {
  +                logger.debug("SQL:" + sql.getStatement());
  +            }
           }
  -        return result;
  +        return sql;
       }
   
       /**
  @@ -121,19 +134,15 @@
        * described by cld
        * @param cld the ClassDescriptor
        */
  -    public String getPreparedSelectByPkStatement(ClassDescriptor cld)
  +    public SelectStatement getPreparedSelectByPkStatement(ClassDescriptor cld)
       {
  -        SqlStatement sql;
  -        String result;
  -
  -        sql = new SqlSelectByPkStatement(cld, logger);
  -        result = sql.getStatement();
  -
  +        SelectStatement sql = new SqlSelectByPkStatement(m_platform, cld, logger);
  +     
           if (logger.isDebugEnabled())
           {
  -            logger.debug("SQL:" + result);
  +            logger.debug("SQL:" + sql.getStatement());
           }
  -        return result;
  +        return sql;
       }
   
       /**
  @@ -141,21 +150,20 @@
        * @param query the Query
        * @param cld the ClassDescriptor
        */
  -    public String getPreparedSelectStatement(Query query, ClassDescriptor cld)
  -    {
  +    public SelectStatement getPreparedSelectStatement(Query query, ClassDescriptor cld)
  +    {     
           SqlCacheKey key = new SqlCacheKey(query, cld, SqlCacheKey.TYPE_SELECT);
  -        String result = (String) m_sqlCacheMap.get(key);
  -        if (result == null)
  +        SelectStatement sql = (SelectStatement) m_sqlCacheMap.get(key);
  +        if (sql == null)
           {
  -            SqlStatement sql = new SqlSelectStatement(m_platform, cld, query, logger);
  -            result = sql.getStatement();
  +            sql = new SqlSelectStatement(m_platform, cld, query, logger);
               if (logger.isDebugEnabled())
               {
  -                logger.debug("SQL:" + result);
  +                logger.debug("SQL:" + sql.getStatement());
               }
  -            m_sqlCacheMap.put(key, result);
  +            m_sqlCacheMap.put(key, sql);
           }
  -        return result;
  +        return sql;
       }
   
       /**
  @@ -163,25 +171,29 @@
        * described by cld
        * @param cld the ClassDescriptor
        */
  -    public String getPreparedUpdateStatement(ClassDescriptor cld)
  +    public SqlStatement getPreparedUpdateStatement(ClassDescriptor cld)
       {
  -        SqlStatement sql;
  -        String result;
  -        ProcedureDescriptor pd = cld.getUpdateProcedure();
  -
  -        if (pd == null)
  -        {
  -            sql = new SqlUpdateStatement(cld, logger);
  -        }
  -        else
  +        SqlForClass sfc = getSqlForClass(cld);
  +        SqlStatement result = sfc.getUpdateSql();
  +        if(result == null)
           {
  -            sql = new SqlProcedureStatement(pd, logger);
  -        }
  -        result = sql.getStatement();
  +            ProcedureDescriptor pd = cld.getUpdateProcedure();
   
  -        if (logger.isDebugEnabled())
  -        {
  -            logger.debug("SQL:" + result);
  +            if(pd == null)
  +            {
  +                result = new SqlUpdateStatement(cld, logger);
  +            }
  +            else
  +            {
  +                result = new SqlProcedureStatement(pd, logger);
  +            }
  +            // set the sql string
  +            sfc.setUpdateSql(result);
  +
  +            if(logger.isDebugEnabled())
  +            {
  +                logger.debug("SQL:" + result.getStatement());
  +            }
           }
           return result;
       }
  @@ -273,21 +285,20 @@
        * @param query the Query
        * @param cld the ClassDescriptor
        */
  -    public String getSelectStatementDep(Query query, ClassDescriptor cld)
  +    public SelectStatement getSelectStatementDep(Query query, ClassDescriptor cld)
       {
           SqlCacheKey key = new SqlCacheKey(query, cld, SqlCacheKey.TYPE_SELECT);
  -        String result = (String) m_sqlCacheMap.get(key);
  -        if (result == null)
  +        SelectStatement sql = (SelectStatement) m_sqlCacheMap.get(key);
  +        if (sql == null)
           {
  -            SqlStatement sql = new SqlSelectStatement(m_platform, cld, query, logger);
  -            result = sql.getStatement();
  +            sql = new SqlSelectStatement(m_platform, cld, query, logger);
               if (logger.isDebugEnabled())
               {
  -                logger.debug("SQL:" + result);
  +                logger.debug("SQL:" + sql.getStatement());
               }
  -            m_sqlCacheMap.put(key, result);
  +            m_sqlCacheMap.put(key, sql);
           }
  -        return result;
  +        return sql;
   
       }
   
  @@ -397,8 +408,9 @@
           
           if (attributeOrQuery instanceof Query)
           {
  -            Query q = (Query)attributeOrQuery;
  -            result = getPreparedSelectStatement(q,cld.getRepository().getDescriptorFor(q.getSearchClass()));
  +            Query q = (Query) attributeOrQuery;
  +            result = getPreparedSelectStatement(q, cld.getRepository().getDescriptorFor(q.getSearchClass()))
  +                    .getStatement();
           }   
           else
           {
  @@ -528,22 +540,9 @@
        * @param query the Query
        * @param cld the ClassDescriptor
        */
  -    public String getPreparedDeleteStatement(Query query, ClassDescriptor cld)
  +    public SqlStatement getPreparedDeleteStatement(Query query, ClassDescriptor cld)
       {
  -        SqlCacheKey key = new SqlCacheKey(query, cld, SqlCacheKey.TYPE_DELETE);
  -        String result = (String) m_sqlCacheMap.get(key);
  -        if (result == null)
  -        {
  -            SqlStatement sql;
  -            sql = new SqlDeleteByQuery(m_platform, cld, query, logger);
  -            result = sql.getStatement();
  -            m_sqlCacheMap.put(key, result);
  -            if (logger.isDebugEnabled())
  -            {
  -                logger.debug("SQL:" + result);
  -            }
  -        }
  -        return result;
  +        return new SqlDeleteByQuery(m_platform, cld, query, logger);
       }
   
       /* (non-Javadoc)
  @@ -554,4 +553,101 @@
           return m_platform;
       }
   
  +    /**
  +     * Returns the {@link SqlForClass} instance for
  +     * the given class descriptor.
  +     *
  +     * @param cld The class descriptor.
  +     * @return The {@link SqlForClass}.
  +     */
  +    protected SqlForClass getSqlForClass(ClassDescriptor cld)
  +    {
  +        SqlForClass result = (SqlForClass) sqlForClass.get(cld);
  +        if(result == null)
  +        {
  +            result = newInstanceSqlForClass();
  +            sqlForClass.put(cld, result);
  +        }
  +        return result;
  +    }
  +
  +    /**
  +     * User who want to extend this implementation can override this method to use
  +     * their own (extended) version of
  +     * {@link org.apache.ojb.broker.accesslayer.sql.SqlGeneratorDefaultImpl.SqlForClass}.
  +     *
  +     * @return A new instance.
  +     */
  +    protected SqlForClass newInstanceSqlForClass()
  +    {
  +        return new SqlForClass();
  +    }
  +
  +    //===================================================================
  +    // inner class
  +    //===================================================================
  +
  +    /**
  +     * This class serves as a cache for sql-Statements
  +     * used for persistence operations.
  +     */
  +    public static class SqlForClass
  +    {
  +        private SqlStatement deleteSql;
  +        private SqlStatement insertSql;
  +        private SqlStatement updateSql;
  +        private SelectStatement selectByPKSql;
  +        private SqlStatement selectExists;
  +
  +        public SqlStatement getDeleteSql()
  +        {
  +            return deleteSql;
  +        }
  +
  +        public void setDeleteSql(SqlStatement deleteSql)
  +        {
  +            this.deleteSql = deleteSql;
  +        }
  +
  +        public SqlStatement getInsertSql()
  +        {
  +            return insertSql;
  +        }
  +
  +        public void setInsertSql(SqlStatement insertSql)
  +        {
  +            this.insertSql = insertSql;
  +        }
  +
  +        public SqlStatement getUpdateSql()
  +        {
  +            return updateSql;
  +        }
  +
  +        public void setUpdateSql(SqlStatement updateSql)
  +        {
  +            this.updateSql = updateSql;
  +        }
  +
  +        public SelectStatement getSelectByPKSql()
  +        {
  +            return selectByPKSql;
  +        }
  +
  +        public void setSelectByPKSql(SelectStatement selectByPKSql)
  +        {
  +            this.selectByPKSql = selectByPKSql;
  +        }
  +
  +        public SqlStatement getSelectExists()
  +        {
  +            return selectExists;
  +        }
  +
  +        public void setSelectExists(SqlStatement selectExists)
  +        {
  +            this.selectExists = selectExists;
  +        }
  +    }
  +
   }
  
  
  
  No                   revision
  
  Index: SqlGeneratorDefaultImpl.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/accesslayer/sql/SqlGeneratorDefaultImpl.java,v
  retrieving revision 1.23.2.1
  retrieving revision 1.23.2.2
  diff -u -r1.23.2.1 -r1.23.2.2
  --- SqlGeneratorDefaultImpl.java	13 Jan 2005 19:20:03 -0000	1.23.2.1
  +++ SqlGeneratorDefaultImpl.java	5 Oct 2005 18:01:26 -0000	1.23.2.2
  @@ -17,6 +17,7 @@
   
   import java.util.Collection;
   import java.util.Enumeration;
  +import java.util.HashMap;
   import java.util.Map;
   import java.util.WeakHashMap;
   
  @@ -48,7 +49,9 @@
   {
       private Logger logger = LoggerFactory.getLogger(SqlGeneratorDefaultImpl.class);
   
  -    private Map m_sqlCacheMap = new WeakHashMap();
  +    /** Cache for {@link SqlForClass} instances, keyed per class descriptor. */
  +    private HashMap sqlForClass = new HashMap();
  +    private HashMap m_sqlCacheMap = new HashMap();
       private Platform m_platform;
   
       /**
  @@ -65,27 +68,32 @@
        * described by cld.
        * @param cld the ClassDescriptor
        */
  -    public String getPreparedDeleteStatement(ClassDescriptor cld)
  +    public SqlStatement getPreparedDeleteStatement(ClassDescriptor cld)
       {
           SqlStatement sql;
  -        String result;
  -        ProcedureDescriptor pd = cld.getDeleteProcedure();
  -
  -        if (pd == null)
  -        {
  -            sql = new SqlDeleteByPkStatement(cld, logger);
  -        }
  -        else
  +        SqlForClass sfc = getSqlForClass(cld);
  +        sql = sfc.getDeleteSql();
  +        if(sql == null)
           {
  -            sql = new SqlProcedureStatement(pd, logger);
  -        }
  -        result = sql.getStatement();
  +            ProcedureDescriptor pd = cld.getDeleteProcedure();
   
  -        if (logger.isDebugEnabled())
  -        {
  -            logger.debug("SQL:" + result);
  +            if(pd == null)
  +            {
  +                sql = new SqlDeleteByPkStatement(cld, logger);
  +            }
  +            else
  +            {
  +                sql = new SqlProcedureStatement(pd, logger);
  +            }
  +            // set the sql string
  +            sfc.setDeleteSql(sql);
  +
  +            if(logger.isDebugEnabled())
  +            {
  +                logger.debug("SQL:" + sql.getStatement());
  +            }
           }
  -        return result;
  +        return sql;
       }
   
       /**
  @@ -93,27 +101,32 @@
        * described by cld.
        * @param cld the ClassDescriptor
        */
  -    public String getPreparedInsertStatement(ClassDescriptor cld)
  +    public SqlStatement getPreparedInsertStatement(ClassDescriptor cld)
       {
           SqlStatement sql;
  -        String result;
  -        ProcedureDescriptor pd = cld.getInsertProcedure();
  -
  -        if (pd == null)
  -        {
  -            sql = new SqlInsertStatement(cld, logger);
  -        }
  -        else
  +        SqlForClass sfc = getSqlForClass(cld);
  +        sql = sfc.getInsertSql();
  +        if(sql == null)
           {
  -            sql = new SqlProcedureStatement(pd, logger);
  -        }
  -        result = sql.getStatement();
  +            ProcedureDescriptor pd = cld.getInsertProcedure();
   
  -        if (logger.isDebugEnabled())
  -        {
  -            logger.debug("SQL:" + result);
  +            if(pd == null)
  +            {
  +                sql = new SqlInsertStatement(cld, logger);
  +            }
  +            else
  +            {
  +                sql = new SqlProcedureStatement(pd, logger);
  +            }
  +            // set the sql string
  +            sfc.setInsertSql(sql);
  +
  +            if(logger.isDebugEnabled())
  +            {
  +                logger.debug("SQL:" + sql.getStatement());
  +            }
           }
  -        return result;
  +        return sql;
       }
   
       /**
  @@ -121,19 +134,15 @@
        * described by cld
        * @param cld the ClassDescriptor
        */
  -    public String getPreparedSelectByPkStatement(ClassDescriptor cld)
  +    public SelectStatement getPreparedSelectByPkStatement(ClassDescriptor cld)
       {
  -        SqlStatement sql;
  -        String result;
  -
  -        sql = new SqlSelectByPkStatement(cld, logger);
  -        result = sql.getStatement();
  -
  +        SelectStatement sql = new SqlSelectByPkStatement(m_platform, cld, logger);
  +     
           if (logger.isDebugEnabled())
           {
  -            logger.debug("SQL:" + result);
  +            logger.debug("SQL:" + sql.getStatement());
           }
  -        return result;
  +        return sql;
       }
   
       /**
  @@ -141,21 +150,20 @@
        * @param query the Query
        * @param cld the ClassDescriptor
        */
  -    public String getPreparedSelectStatement(Query query, ClassDescriptor cld)
  -    {
  +    public SelectStatement getPreparedSelectStatement(Query query, ClassDescriptor cld)
  +    {     
           SqlCacheKey key = new SqlCacheKey(query, cld, SqlCacheKey.TYPE_SELECT);
  -        String result = (String) m_sqlCacheMap.get(key);
  -        if (result == null)
  +        SelectStatement sql = (SelectStatement) m_sqlCacheMap.get(key);
  +        if (sql == null)
           {
  -            SqlStatement sql = new SqlSelectStatement(m_platform, cld, query, logger);
  -            result = sql.getStatement();
  +            sql = new SqlSelectStatement(m_platform, cld, query, logger);
               if (logger.isDebugEnabled())
               {
  -                logger.debug("SQL:" + result);
  +                logger.debug("SQL:" + sql.getStatement());
               }
  -            m_sqlCacheMap.put(key, result);
  +            m_sqlCacheMap.put(key, sql);
           }
  -        return result;
  +        return sql;
       }
   
       /**
  @@ -163,25 +171,29 @@
        * described by cld
        * @param cld the ClassDescriptor
        */
  -    public String getPreparedUpdateStatement(ClassDescriptor cld)
  +    public SqlStatement getPreparedUpdateStatement(ClassDescriptor cld)
       {
  -        SqlStatement sql;
  -        String result;
  -        ProcedureDescriptor pd = cld.getUpdateProcedure();
  -
  -        if (pd == null)
  -        {
  -            sql = new SqlUpdateStatement(cld, logger);
  -        }
  -        else
  +        SqlForClass sfc = getSqlForClass(cld);
  +        SqlStatement result = sfc.getUpdateSql();
  +        if(result == null)
           {
  -            sql = new SqlProcedureStatement(pd, logger);
  -        }
  -        result = sql.getStatement();
  +            ProcedureDescriptor pd = cld.getUpdateProcedure();
   
  -        if (logger.isDebugEnabled())
  -        {
  -            logger.debug("SQL:" + result);
  +            if(pd == null)
  +            {
  +                result = new SqlUpdateStatement(cld, logger);
  +            }
  +            else
  +            {
  +                result = new SqlProcedureStatement(pd, logger);
  +            }
  +            // set the sql string
  +            sfc.setUpdateSql(result);
  +
  +            if(logger.isDebugEnabled())
  +            {
  +                logger.debug("SQL:" + result.getStatement());
  +            }
           }
           return result;
       }
  @@ -273,21 +285,20 @@
        * @param query the Query
        * @param cld the ClassDescriptor
        */
  -    public String getSelectStatementDep(Query query, ClassDescriptor cld)
  +    public SelectStatement getSelectStatementDep(Query query, ClassDescriptor cld)
       {
           SqlCacheKey key = new SqlCacheKey(query, cld, SqlCacheKey.TYPE_SELECT);
  -        String result = (String) m_sqlCacheMap.get(key);
  -        if (result == null)
  +        SelectStatement sql = (SelectStatement) m_sqlCacheMap.get(key);
  +        if (sql == null)
           {
  -            SqlStatement sql = new SqlSelectStatement(m_platform, cld, query, logger);
  -            result = sql.getStatement();
  +            sql = new SqlSelectStatement(m_platform, cld, query, logger);
               if (logger.isDebugEnabled())
               {
  -                logger.debug("SQL:" + result);
  +                logger.debug("SQL:" + sql.getStatement());
               }
  -            m_sqlCacheMap.put(key, result);
  +            m_sqlCacheMap.put(key, sql);
           }
  -        return result;
  +        return sql;
   
       }
   
  @@ -397,8 +408,9 @@
           
           if (attributeOrQuery instanceof Query)
           {
  -            Query q = (Query)attributeOrQuery;
  -            result = getPreparedSelectStatement(q,cld.getRepository().getDescriptorFor(q.getSearchClass()));
  +            Query q = (Query) attributeOrQuery;
  +            result = getPreparedSelectStatement(q, cld.getRepository().getDescriptorFor(q.getSearchClass()))
  +                    .getStatement();
           }   
           else
           {
  @@ -528,22 +540,9 @@
        * @param query the Query
        * @param cld the ClassDescriptor
        */
  -    public String getPreparedDeleteStatement(Query query, ClassDescriptor cld)
  +    public SqlStatement getPreparedDeleteStatement(Query query, ClassDescriptor cld)
       {
  -        SqlCacheKey key = new SqlCacheKey(query, cld, SqlCacheKey.TYPE_DELETE);
  -        String result = (String) m_sqlCacheMap.get(key);
  -        if (result == null)
  -        {
  -            SqlStatement sql;
  -            sql = new SqlDeleteByQuery(m_platform, cld, query, logger);
  -            result = sql.getStatement();
  -            m_sqlCacheMap.put(key, result);
  -            if (logger.isDebugEnabled())
  -            {
  -                logger.debug("SQL:" + result);
  -            }
  -        }
  -        return result;
  +        return new SqlDeleteByQuery(m_platform, cld, query, logger);
       }
   
       /* (non-Javadoc)
  @@ -554,4 +553,101 @@
           return m_platform;
       }
   
  +    /**
  +     * Returns the {@link SqlForClass} instance for
  +     * the given class descriptor.
  +     *
  +     * @param cld The class descriptor.
  +     * @return The {@link SqlForClass}.
  +     */
  +    protected SqlForClass getSqlForClass(ClassDescriptor cld)
  +    {
  +        SqlForClass result = (SqlForClass) sqlForClass.get(cld);
  +        if(result == null)
  +        {
  +            result = newInstanceSqlForClass();
  +            sqlForClass.put(cld, result);
  +        }
  +        return result;
  +    }
  +
  +    /**
  +     * User who want to extend this implementation can override this method to use
  +     * their own (extended) version of
  +     * {@link org.apache.ojb.broker.accesslayer.sql.SqlGeneratorDefaultImpl.SqlForClass}.
  +     *
  +     * @return A new instance.
  +     */
  +    protected SqlForClass newInstanceSqlForClass()
  +    {
  +        return new SqlForClass();
  +    }
  +
  +    //===================================================================
  +    // inner class
  +    //===================================================================
  +
  +    /**
  +     * This class serves as a cache for sql-Statements
  +     * used for persistence operations.
  +     */
  +    public static class SqlForClass
  +    {
  +        private SqlStatement deleteSql;
  +        private SqlStatement insertSql;
  +        private SqlStatement updateSql;
  +        private SelectStatement selectByPKSql;
  +        private SqlStatement selectExists;
  +
  +        public SqlStatement getDeleteSql()
  +        {
  +            return deleteSql;
  +        }
  +
  +        public void setDeleteSql(SqlStatement deleteSql)
  +        {
  +            this.deleteSql = deleteSql;
  +        }
  +
  +        public SqlStatement getInsertSql()
  +        {
  +            return insertSql;
  +        }
  +
  +        public void setInsertSql(SqlStatement insertSql)
  +        {
  +            this.insertSql = insertSql;
  +        }
  +
  +        public SqlStatement getUpdateSql()
  +        {
  +            return updateSql;
  +        }
  +
  +        public void setUpdateSql(SqlStatement updateSql)
  +        {
  +            this.updateSql = updateSql;
  +        }
  +
  +        public SelectStatement getSelectByPKSql()
  +        {
  +            return selectByPKSql;
  +        }
  +
  +        public void setSelectByPKSql(SelectStatement selectByPKSql)
  +        {
  +            this.selectByPKSql = selectByPKSql;
  +        }
  +
  +        public SqlStatement getSelectExists()
  +        {
  +            return selectExists;
  +        }
  +
  +        public void setSelectExists(SqlStatement selectExists)
  +        {
  +            this.selectExists = selectExists;
  +        }
  +    }
  +
   }
  
  
  
  1.1.2.1   +2 -5      db-ojb/src/java/org/apache/ojb/broker/accesslayer/sql/SelectStatement.java
  
  Index: SelectStatement.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/accesslayer/sql/SelectStatement.java,v
  retrieving revision 1.1
  retrieving revision 1.1.2.1
  diff -u -r1.1 -r1.1.2.1
  --- SelectStatement.java	3 Oct 2005 17:35:24 -0000	1.1
  +++ SelectStatement.java	5 Oct 2005 18:01:26 -0000	1.1.2.1
  @@ -15,11 +15,8 @@
    * limitations under the License.
    */
   
  -import java.lang.Object;
  -import java.sql.ResultSet;
  -
  -import org.apache.ojb.broker.query.Query;
   import org.apache.ojb.broker.metadata.FieldDescriptor;
  +import org.apache.ojb.broker.query.Query;
   
   /**
    * This class
  
  
  
  No                   revision
  No                   revision
  1.24.2.3  +26 -2     db-ojb/src/java/org/apache/ojb/broker/util/SqlHelper.java
  
  Index: SqlHelper.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/util/SqlHelper.java,v
  retrieving revision 1.24.2.2
  retrieving revision 1.24.2.3
  diff -u -r1.24.2.2 -r1.24.2.3
  --- SqlHelper.java	8 Jun 2005 19:45:30 -0000	1.24.2.2
  +++ SqlHelper.java	5 Oct 2005 18:01:28 -0000	1.24.2.3
  @@ -1,5 +1,8 @@
   package org.apache.ojb.broker.util;
   
  +import java.sql.ResultSet;
  +import java.sql.SQLException;
  +
   import org.apache.commons.lang.StringUtils;
   
   /* Copyright 2002-2004 The Apache Software Foundation
  @@ -25,7 +28,10 @@
    */
   public class SqlHelper
   {
  -	/**
  +    /** define the name of the pseudo column holding the class to be instantiated. */
  +    public static final String OJB_CLASS_COLUMN = "OJB_CLAZZ"; 
  +
  +    /**
   	 * Helper Class for a split column <br>
   	 * ie: sum (distinct amount) as theAmount
   	 * 
  @@ -120,4 +126,22 @@
           
           return new PathInfo(aPath, prefix, colName.trim(), suffix);
       }
  +    
  +    /**
  +     * Returns the name of the class to be instantiated.
  +     * @param rs the Resultset
  +     * @return null if the column is not available
  +     */
  +    public static String getOjbClassName(ResultSet rs)
  +    {
  +        try
  +        {
  +            return rs.getString(OJB_CLASS_COLUMN);
  +        }
  +        catch (SQLException e)
  +        {
  +            return null;
  +        }
  +    }
  +
   }
  
  
  
  No                   revision
  No                   revision
  1.7.2.14  +2 -2      db-ojb/src/test/org/apache/ojb/broker/InheritanceMultipleTableTest.java
  
  Index: InheritanceMultipleTableTest.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/test/org/apache/ojb/broker/InheritanceMultipleTableTest.java,v
  retrieving revision 1.7.2.13
  retrieving revision 1.7.2.14
  diff -u -r1.7.2.13 -r1.7.2.14
  --- InheritanceMultipleTableTest.java	18 Sep 2005 12:06:46 -0000	1.7.2.13
  +++ InheritanceMultipleTableTest.java	5 Oct 2005 18:01:28 -0000	1.7.2.14
  @@ -915,7 +915,7 @@
           query.setPathOuterJoin("executives");	
           
           SqlGenerator sqlg = broker.serviceSqlGenerator();
  -        String sql = sqlg.getPreparedSelectStatement(query, broker.getClassDescriptor(Company.class));
  +        String sql = sqlg.getPreparedSelectStatement(query, broker.getClassDescriptor(Company.class)).getStatement();
   
           result = broker.getCollectionByQuery(query);
           assertEquals(2, result.size());								// should retrieve both companies
  
  
  
  1.61.2.16 +2 -2      db-ojb/src/test/org/apache/ojb/broker/QueryTest.java
  
  Index: QueryTest.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/test/org/apache/ojb/broker/QueryTest.java,v
  retrieving revision 1.61.2.15
  retrieving revision 1.61.2.16
  diff -u -r1.61.2.15 -r1.61.2.16
  --- QueryTest.java	8 Aug 2005 13:18:48 -0000	1.61.2.15
  +++ QueryTest.java	5 Oct 2005 18:01:28 -0000	1.61.2.16
  @@ -1716,7 +1716,7 @@
           q.setAttributes(new String[]{"articleId", "price+10"});
           ClassDescriptor cd = broker.getClassDescriptor(q.getBaseClass());
           SqlGenerator sqlg = broker.serviceSqlGenerator();
  -        String sql = sqlg.getPreparedSelectStatement(q, cd);
  +        String sql = sqlg.getPreparedSelectStatement(q, cd).getStatement();
           
           assertTrue("Bad query generated. the 'price' field has not table prefix. SQL Output: " + sql, sql
                   .equalsIgnoreCase("SELECT A0.Artikel_Nr,A0.Einzelpreis+10 FROM Artikel A0"));
  
  
  
  No                   revision
  No                   revision
  1.1.2.2   +5 -5      db-ojb/src/test/org/apache/ojb/compare/PerformanceJdbcFailoverTest.java
  
  Index: PerformanceJdbcFailoverTest.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/test/org/apache/ojb/compare/PerformanceJdbcFailoverTest.java,v
  retrieving revision 1.1.2.1
  retrieving revision 1.1.2.2
  diff -u -r1.1.2.1 -r1.1.2.2
  --- PerformanceJdbcFailoverTest.java	26 Apr 2005 22:03:16 -0000	1.1.2.1
  +++ PerformanceJdbcFailoverTest.java	5 Oct 2005 18:01:29 -0000	1.1.2.2
  @@ -198,7 +198,7 @@
           // Use the OJB SqlGenerator to generate SQL Statements. All details about
           // Table and column names are read from the repository.xml file.
           ClassDescriptor cld = broker.getClassDescriptor(PerformanceArticle.class);
  -        String sql = broker.serviceSqlGenerator().getPreparedDeleteStatement(cld);
  +        String sql = broker.serviceSqlGenerator().getPreparedDeleteStatement(cld).getStatement();
   
           logger.debug("delete stmt: " + sql);
   
  @@ -261,7 +261,7 @@
           // Use the OJB SqlGenerator to generate SQL Statements. All details about
           // Table and column names are read from the repository.xml file.
           ClassDescriptor cld = broker.getClassDescriptor(PerformanceArticle.class);
  -        String sql = broker.serviceSqlGenerator().getPreparedInsertStatement(cld);
  +        String sql = broker.serviceSqlGenerator().getPreparedInsertStatement(cld).getStatement();
   
           logger.debug("insert stmt: " + sql);
   
  @@ -382,7 +382,7 @@
           // Use the OJB SqlGenerator to generate SQL Statements. All details about
           // Table and column names are read from the repository.xml file.
           ClassDescriptor cld = broker.getClassDescriptor(PerformanceArticle.class);
  -        String sql = broker.serviceSqlGenerator().getPreparedSelectByPkStatement(cld);
  +        String sql = broker.serviceSqlGenerator().getPreparedSelectByPkStatement(cld).getStatement();
           logger.debug("select stmt: " + sql);
           long start = System.currentTimeMillis();
   
  @@ -474,7 +474,7 @@
           // Use the OJB SqlGenerator to generate SQL Statements. All details about
           // Table and column names are read from the repository.xml file.
           ClassDescriptor cld = broker.getClassDescriptor(PerformanceArticle.class);
  -        String sql = broker.serviceSqlGenerator().getPreparedSelectStatement(query, cld);
  +        String sql = broker.serviceSqlGenerator().getPreparedSelectStatement(query, cld).getStatement();
   
           logger.debug("select stmt: " + sql);
           long start = System.currentTimeMillis();
  @@ -562,7 +562,7 @@
           // Use the OJB SqlGenerator to generate SQL Statements. All details about
           // Table and column names are read from the repository.xml file.
           ClassDescriptor cld = broker.getClassDescriptor(PerformanceArticle.class);
  -        String sql = broker.serviceSqlGenerator().getPreparedUpdateStatement(cld);
  +        String sql = broker.serviceSqlGenerator().getPreparedUpdateStatement(cld).getStatement();
           logger.debug("update stmt: " + sql);
   
           // update all objects
  
  
  
  1.1.2.2   +5 -5      db-ojb/src/test/org/apache/ojb/compare/PerformanceJdbcTest.java
  
  Index: PerformanceJdbcTest.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/test/org/apache/ojb/compare/PerformanceJdbcTest.java,v
  retrieving revision 1.1.2.1
  retrieving revision 1.1.2.2
  diff -u -r1.1.2.1 -r1.1.2.2
  --- PerformanceJdbcTest.java	26 Apr 2005 22:03:16 -0000	1.1.2.1
  +++ PerformanceJdbcTest.java	5 Oct 2005 18:01:29 -0000	1.1.2.2
  @@ -65,7 +65,7 @@
           // Use the OJB SqlGenerator to generate SQL Statements. All details about
           // Table and column names are read from the repository.xml file.
           ClassDescriptor cld = broker.getClassDescriptor(PerformanceArticle.class);
  -        String sql = broker.serviceSqlGenerator().getPreparedDeleteStatement(cld);
  +        String sql = broker.serviceSqlGenerator().getPreparedDeleteStatement(cld).getStatement();
   
           logger.debug("delete stmt: " + sql);
   
  @@ -106,7 +106,7 @@
           // Use the OJB SqlGenerator to generate SQL Statements. All details about
           // Table and column names are read from the repository.xml file.
           ClassDescriptor cld = broker.getClassDescriptor(PerformanceArticle.class);
  -        String sql = broker.serviceSqlGenerator().getPreparedInsertStatement(cld);
  +        String sql = broker.serviceSqlGenerator().getPreparedInsertStatement(cld).getStatement();
   
           logger.debug("insert stmt: " + sql);
   
  @@ -173,7 +173,7 @@
           // Use the OJB SqlGenerator to generate SQL Statements. All details about
           // Table and column names are read from the repository.xml file.
           ClassDescriptor cld = broker.getClassDescriptor(PerformanceArticle.class);
  -        String sql = broker.serviceSqlGenerator().getPreparedSelectByPkStatement(cld);
  +        String sql = broker.serviceSqlGenerator().getPreparedSelectByPkStatement(cld).getStatement();
           logger.debug("select stmt: " + sql);
   
           String colId = cld.getFieldDescriptorByName("articleId").getColumnName();
  @@ -243,7 +243,7 @@
           // Use the OJB SqlGenerator to generate SQL Statements. All details about
           // Table and column names are read from the repository.xml file.
           ClassDescriptor cld = broker.getClassDescriptor(PerformanceArticle.class);
  -        String sql = broker.serviceSqlGenerator().getPreparedSelectStatement(query, cld);
  +        String sql = broker.serviceSqlGenerator().getPreparedSelectStatement(query, cld).getStatement();
   
           logger.debug("select stmt: " + sql);
   
  @@ -310,7 +310,7 @@
           // Use the OJB SqlGenerator to generate SQL Statements. All details about
           // Table and column names are read from the repository.xml file.
           ClassDescriptor cld = broker.getClassDescriptor(PerformanceArticle.class);
  -        String sql = broker.serviceSqlGenerator().getPreparedUpdateStatement(cld);
  +        String sql = broker.serviceSqlGenerator().getPreparedUpdateStatement(cld).getStatement();
           logger.debug("update stmt: " + sql);
   
           // update all objects
  
  
  
  No                   revision
  No                   revision
  1.17.2.13 +11 -2     db-ojb/src/java/org/apache/ojb/broker/core/QueryReferenceBroker.java
  
  Index: QueryReferenceBroker.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/core/QueryReferenceBroker.java,v
  retrieving revision 1.17.2.12
  retrieving revision 1.17.2.13
  diff -u -r1.17.2.12 -r1.17.2.13
  --- QueryReferenceBroker.java	26 Aug 2005 19:26:39 -0000	1.17.2.12
  +++ QueryReferenceBroker.java	5 Oct 2005 18:01:29 -0000	1.17.2.13
  @@ -43,6 +43,7 @@
   import org.apache.ojb.broker.metadata.FieldHelper;
   import org.apache.ojb.broker.metadata.MetadataException;
   import org.apache.ojb.broker.metadata.ObjectReferenceDescriptor;
  +import org.apache.ojb.broker.metadata.SuperReferenceDescriptor;
   import org.apache.ojb.broker.metadata.fieldaccess.PersistentField;
   import org.apache.ojb.broker.query.Criteria;
   import org.apache.ojb.broker.query.Query;
  @@ -365,6 +366,7 @@
                   RelationshipPrefetcher prefetcher;
                   ArrayList owners = (ArrayList) entry.getValue();
   
  +//                if (ord instanceof SuperReferenceDescriptor || ord.isLazy() || (ord.getItemProxyClass() != null))
                   if (ord.isLazy() || (ord.getItemProxyClass() != null))
                   {
                       continue;
  @@ -391,7 +393,7 @@
       {
           PersistentField refField;
           Object refObj = null;
  -
  +        
           if (forced || rds.getCascadeRetrieve())
           {
               pb.getInternalCache().enableMaterializationCache();
  @@ -407,6 +409,13 @@
                   else if ( pb.serviceObjectCache().lookup(id) != null )
                   {
                       refObj = pb.doGetObjectByIdentity(id);
  +                    if (rds.isSuperReferenceDescriptor()) 
  +                    {
  +                        // walk the super-references
  +                        ClassDescriptor superCld = cld.getRepository().getDescriptorFor(rds.getItemClass());
  +                        retrieveReferences(refObj, superCld, false);
  +                        retrieveCollections(refObj, superCld, false);                        
  +                    }
                   }
                   else if ((m_retrievalTasks != null)
                           && !rds.isLazy()
  
  
  
  No                   revision
  No                   revision
  1.50.2.8  +7 -1      db-ojb/src/java/org/apache/ojb/broker/metadata/DescriptorRepository.java
  
  Index: DescriptorRepository.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/metadata/DescriptorRepository.java,v
  retrieving revision 1.50.2.7
  retrieving revision 1.50.2.8
  diff -u -r1.50.2.7 -r1.50.2.8
  --- DescriptorRepository.java	14 Aug 2005 16:00:33 -0000	1.50.2.7
  +++ DescriptorRepository.java	5 Oct 2005 18:01:29 -0000	1.50.2.8
  @@ -156,6 +156,12 @@
               synchronized (extentTable)
               {
                   ClassDescriptor cld = (ClassDescriptor) extentTable.get(clazz.getName());
  +                if (cld == null)
  +                {
  +                    // walk the super-references
  +                    cld = getDescriptorFor(clazz).getSuperClassDescriptor();
  +                }
  +                
                   if (cld != null)
                   {
                       // fix by Mark Rowell
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: ojb-dev-unsubscribe@db.apache.org
For additional commands, e-mail: ojb-dev-help@db.apache.org