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 ar...@apache.org on 2005/10/10 02:02:15 UTC

cvs commit: db-ojb/src/java/org/apache/ojb/broker/accesslayer/sql SqlDeleteByPkStatement.java SqlExistStatement.java SqlGeneratorDefaultImpl.java SqlInsertStatement.java SqlPkStatement.java SqlSelectByPkStatement.java SqlSelectStatement.java SqlUpdateStatement.java SqlCacheKey.java

arminw      2005/10/09 17:02:15

  Modified:    src/java/org/apache/ojb/broker/accesslayer/sql Tag:
                        OJB_1_0_RELEASE SqlDeleteByPkStatement.java
                        SqlExistStatement.java SqlGeneratorDefaultImpl.java
                        SqlInsertStatement.java SqlPkStatement.java
                        SqlSelectByPkStatement.java SqlSelectStatement.java
                        SqlUpdateStatement.java
  Removed:     src/java/org/apache/ojb/broker/accesslayer/sql Tag:
                        OJB_1_0_RELEASE SqlCacheKey.java
  Log:
  use weak references to metadata instances like ClassDescriptor/FieldDescriptors to allow GC, code cleanup
  
  Revision  Changes    Path
  No                   revision
  No                   revision
  1.6.2.1   +27 -23    db-ojb/src/java/org/apache/ojb/broker/accesslayer/sql/SqlDeleteByPkStatement.java
  
  Index: SqlDeleteByPkStatement.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/accesslayer/sql/SqlDeleteByPkStatement.java,v
  retrieving revision 1.6
  retrieving revision 1.6.2.1
  diff -u -r1.6 -r1.6.2.1
  --- SqlDeleteByPkStatement.java	4 Apr 2004 23:53:32 -0000	1.6
  +++ SqlDeleteByPkStatement.java	10 Oct 2005 00:02:14 -0000	1.6.2.1
  @@ -26,31 +26,35 @@
    */
   public class SqlDeleteByPkStatement extends SqlPkStatement
   {
  +    private String sql;
   
  -	/**
  -	 * Constructor for SqlDeleteByPkStatement.
  -	 * @param cld
  -	 * @param logger
  -	 */
  -	public SqlDeleteByPkStatement(ClassDescriptor cld, Logger logger)
  -	{
  +    /**
  +     * Constructor for SqlDeleteByPkStatement.
  +     *
  +     * @param cld
  +     * @param logger
  +     */
  +    public SqlDeleteByPkStatement(ClassDescriptor cld, Logger logger)
  +    {
           super(cld, logger);
  -	}
  +    }
   
  -	/**
  -	 * @see org.apache.ojb.broker.accesslayer.sql.SqlStatement#getStatement()
  -	 */
  -	public String getStatement()
  -	{
  -        StringBuffer stmt = new StringBuffer(1024);
  -        ClassDescriptor cld = getClassDescriptor();
  -
  -        stmt.append("DELETE FROM ");
  -        appendTable(cld,stmt);
  -        appendWhereClause(cld, true, stmt); //use Locking
  -
  -        return stmt.toString();
  -	}
  +    /** @see SqlStatement#getStatement() */
  +    public String getStatement()
  +    {
  +        if(sql == null)
  +        {
  +            StringBuffer stmt = new StringBuffer(1024);
  +            ClassDescriptor cld = getClassDescriptor();
  +
  +            stmt.append("DELETE FROM ");
  +            appendTable(cld, stmt);
  +            appendWhereClause(cld, true, stmt); //use Locking
  +
  +            sql = stmt.toString();
  +        }
  +        return sql;
  +    }
   
   }
   
  
  
  
  1.4.2.1   +24 -19    db-ojb/src/java/org/apache/ojb/broker/accesslayer/sql/SqlExistStatement.java
  
  Index: SqlExistStatement.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/accesslayer/sql/SqlExistStatement.java,v
  retrieving revision 1.4
  retrieving revision 1.4.2.1
  diff -u -r1.4 -r1.4.2.1
  --- SqlExistStatement.java	4 Apr 2004 23:53:32 -0000	1.4
  +++ SqlExistStatement.java	10 Oct 2005 00:02:14 -0000	1.4.2.1
  @@ -32,31 +32,36 @@
       private static final String SELECT = "SELECT ";
       private static final String FROM = " FROM ";
   
  +    private String sql;
  +
       public SqlExistStatement(ClassDescriptor aCld, Logger aLogger)
       {
           super(aCld, aLogger);
       }
   
  -    /**
  -     * Return SELECT clause for object existence call
  -     */
  +    /** Return SELECT clause for object existence call */
       public String getStatement()
       {
  -        StringBuffer stmt = new StringBuffer(128);
  -        ClassDescriptor cld = getClassDescriptor();
  -
  -        FieldDescriptor[] fieldDescriptors = cld.getPkFields();
  -        if (fieldDescriptors == null || fieldDescriptors.length == 0)
  +        if(sql == null)
           {
  -            throw new OJBRuntimeException("No PK fields defined in metadata for " + cld.getClassNameOfObject());
  -        }
  -        FieldDescriptor field = fieldDescriptors[0];
  +            StringBuffer stmt = new StringBuffer(128);
  +            ClassDescriptor cld = getClassDescriptor();
   
  -        stmt.append(SELECT);
  -        stmt.append(field.getColumnName());
  -        stmt.append(FROM);
  -        stmt.append(cld.getFullTableName());
  -        appendWhereClause(cld, false, stmt);
  -        return stmt.toString();
  +            FieldDescriptor[] fieldDescriptors = cld.getPkFields();
  +            if(fieldDescriptors == null || fieldDescriptors.length == 0)
  +            {
  +                throw new OJBRuntimeException("No PK fields defined in metadata for " + cld.getClassNameOfObject());
  +            }
  +            FieldDescriptor field = fieldDescriptors[0];
  +
  +            stmt.append(SELECT);
  +            stmt.append(field.getColumnName());
  +            stmt.append(FROM);
  +            stmt.append(cld.getFullTableName());
  +            appendWhereClause(cld, false, stmt);
  +
  +            sql = stmt.toString();
  +        }
  +        return sql;
       }
  -}
  +}
  \ No newline at end of file
  
  
  
  1.23.2.3  +72 -58    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.2
  retrieving revision 1.23.2.3
  diff -u -r1.23.2.2 -r1.23.2.3
  --- SqlGeneratorDefaultImpl.java	5 Oct 2005 18:01:26 -0000	1.23.2.2
  +++ SqlGeneratorDefaultImpl.java	10 Oct 2005 00:02:14 -0000	1.23.2.3
  @@ -17,10 +17,9 @@
   
   import java.util.Collection;
   import java.util.Enumeration;
  -import java.util.HashMap;
   import java.util.Map;
  -import java.util.WeakHashMap;
   
  +import org.apache.commons.collections.map.ReferenceIdentityMap;
   import org.apache.ojb.broker.metadata.ClassDescriptor;
   import org.apache.ojb.broker.metadata.ProcedureDescriptor;
   import org.apache.ojb.broker.platforms.Platform;
  @@ -48,19 +47,24 @@
   public class SqlGeneratorDefaultImpl implements SqlGenerator
   {
       private Logger logger = LoggerFactory.getLogger(SqlGeneratorDefaultImpl.class);
  +    private Platform m_platform;
  +    /*
  +    arminw:
  +    TODO: In ClassDescriptor we need support for "field change event" listener if we allow
  +    to change metadata at runtime.
  +    Further on we have to deal with weak references to allow GC of outdated Metadata classes
  +    (key=cld of map have to be a weak reference and the metadata used in the SqlStatement classes too,
  +    because inner class SqlForClass indirectly refer the key=cld in some cases and SqlStatement
  +    implementation classes have references to metadata classes too).
   
  +    Field changes are not reflected in this implementation!
  +    */
       /** Cache for {@link SqlForClass} instances, keyed per class descriptor. */
  -    private HashMap sqlForClass = new HashMap();
  -    private HashMap m_sqlCacheMap = new HashMap();
  -    private Platform m_platform;
  +    private Map sqlForClass = new ReferenceIdentityMap(ReferenceIdentityMap.WEAK, ReferenceIdentityMap.HARD);
   
  -    /**
  -     * Constructor is protected, use getInstance() to retrieve the singleton
  -     * instance of this class.
  -     */
  -    public SqlGeneratorDefaultImpl(Platform pf)
  +    public SqlGeneratorDefaultImpl(Platform platform)
       {
  -        this.m_platform = pf;
  +        this.m_platform = platform;
       }
   
       /**
  @@ -70,9 +74,8 @@
        */
       public SqlStatement getPreparedDeleteStatement(ClassDescriptor cld)
       {
  -        SqlStatement sql;
           SqlForClass sfc = getSqlForClass(cld);
  -        sql = sfc.getDeleteSql();
  +        SqlStatement sql = sfc.getDeleteSql();
           if(sql == null)
           {
               ProcedureDescriptor pd = cld.getDeleteProcedure();
  @@ -99,6 +102,7 @@
       /**
        * generate a prepared INSERT-Statement for the Class
        * described by cld.
  +     *
        * @param cld the ClassDescriptor
        */
       public SqlStatement getPreparedInsertStatement(ClassDescriptor cld)
  @@ -136,32 +140,55 @@
        */
       public SelectStatement getPreparedSelectByPkStatement(ClassDescriptor cld)
       {
  -        SelectStatement sql = new SqlSelectByPkStatement(m_platform, cld, logger);
  -     
  -        if (logger.isDebugEnabled())
  +        SelectStatement sql;
  +        SqlForClass sfc = getSqlForClass(cld);
  +        sql = sfc.getSelectByPKSql();
  +        if(sql == null)
           {
  -            logger.debug("SQL:" + sql.getStatement());
  +            sql = new SqlSelectByPkStatement(m_platform, cld, logger);
  +
  +            // set the sql string
  +            sfc.setSelectByPKSql(sql);
  +
  +            if(logger.isDebugEnabled())
  +            {
  +                logger.debug("SQL:" + sql.getStatement());
  +            }
  +        }
  +        return sql;
  +    }
  +
  +    public SqlStatement getPreparedExistsStatement(ClassDescriptor cld)
  +    {
  +        SqlStatement sql;
  +        SqlForClass sfc = getSqlForClass(cld);
  +        sql = sfc.getSelectExists();
  +        if(sql == null)
  +        {
  +            // TODO: Should we support a procedure call for this too??
  +            sql = new SqlExistStatement(logger, cld);
  +            // set the sql string
  +            sfc.setSelectExists(sql);
  +            if(logger.isDebugEnabled())
  +            {
  +                logger.debug("SQL:" + sql.getStatement());
  +            }
           }
           return sql;
       }
   
       /**
        * generate a select-Statement according to query
  +     *
        * @param query the Query
        * @param cld the ClassDescriptor
        */
       public SelectStatement getPreparedSelectStatement(Query query, ClassDescriptor cld)
  -    {     
  -        SqlCacheKey key = new SqlCacheKey(query, cld, SqlCacheKey.TYPE_SELECT);
  -        SelectStatement sql = (SelectStatement) m_sqlCacheMap.get(key);
  -        if (sql == null)
  +    {
  +        SelectStatement sql = new SqlSelectStatement(m_platform, cld, query, logger);
  +        if (logger.isDebugEnabled())
           {
  -            sql = new SqlSelectStatement(m_platform, cld, query, logger);
  -            if (logger.isDebugEnabled())
  -            {
  -                logger.debug("SQL:" + sql.getStatement());
  -            }
  -            m_sqlCacheMap.put(key, sql);
  +            logger.debug("SQL:" + sql.getStatement());
           }
           return sql;
       }
  @@ -287,19 +314,8 @@
        */
       public SelectStatement getSelectStatementDep(Query query, ClassDescriptor cld)
       {
  -        SqlCacheKey key = new SqlCacheKey(query, cld, SqlCacheKey.TYPE_SELECT);
  -        SelectStatement sql = (SelectStatement) m_sqlCacheMap.get(key);
  -        if (sql == null)
  -        {
  -            sql = new SqlSelectStatement(m_platform, cld, query, logger);
  -            if (logger.isDebugEnabled())
  -            {
  -                logger.debug("SQL:" + sql.getStatement());
  -            }
  -            m_sqlCacheMap.put(key, sql);
  -        }
  -        return sql;
  -
  +        // TODO: Why do we need this method?
  +        return getPreparedSelectStatement(query, cld);
       }
   
       /**
  @@ -335,7 +351,7 @@
                   {
                       case (Criteria.OR) :
                           {
  -                            statement.append(" OR " + addAtStart);
  +                            statement.append(" OR ").append(addAtStart);
                               statement.append(asSQLStatement(pc, cld));
                               statement.append(addAtEnd);
                               break;
  @@ -344,7 +360,7 @@
                           {
                               statement.insert(0, "( ");
                               statement.append(") ");
  -                            statement.append(" AND " + addAtStart);
  +                            statement.append(" AND ").append(addAtStart);
                               statement.append(asSQLStatement(pc, cld));
                               statement.append(addAtEnd);
                               break;
  @@ -376,6 +392,7 @@
   
       /**
        * Answer the SQL-Clause for a SelectionCriteria
  +     *
        * @param c SelectionCriteria
        * @param cld ClassDescriptor
        */
  @@ -385,16 +402,16 @@
               return toSQLClause((FieldCriteria) c, cld);
   
           if (c instanceof NullCriteria)
  -            return toSQLClause((NullCriteria) c, cld);
  +            return toSQLClause((NullCriteria) c);
   
           if (c instanceof BetweenCriteria)
               return toSQLClause((BetweenCriteria) c, cld);
   
           if (c instanceof InCriteria)
  -            return toSQLClause((InCriteria) c, cld);
  +            return toSQLClause((InCriteria) c);
   
           if (c instanceof SqlCriteria)
  -            return toSQLClause((SqlCriteria) c, cld);
  +            return toSQLClause((SqlCriteria) c);
   
           if (c instanceof ExistsCriteria)
               return toSQLClause((ExistsCriteria) c, cld);
  @@ -405,28 +422,27 @@
       private String toSqlClause(Object attributeOrQuery, ClassDescriptor cld)
       {
           String result;
  -        
  +
           if (attributeOrQuery instanceof Query)
           {
               Query q = (Query) attributeOrQuery;
               result = getPreparedSelectStatement(q, cld.getRepository().getDescriptorFor(q.getSearchClass()))
                       .getStatement();
  -        }   
  +        }
           else
           {
  -           result = (String)attributeOrQuery; 
  -        } 
  +           result = (String)attributeOrQuery;
  +        }
   
           return result;
  -    } 
  -    
  +    }
  +
       /**
        * Answer the SQL-Clause for a NullCriteria
        *
        * @param c NullCriteria
  -     * @param cld ClassDescriptor
        */
  -    private String toSQLClause(NullCriteria c, ClassDescriptor cld)
  +    private String toSQLClause(NullCriteria c)
       {
           String colName = (String)c.getAttribute();
           return colName + c.getClause();
  @@ -460,9 +476,8 @@
        * Answer the SQL-Clause for an InCriteria
        *
        * @param c SelectionCriteria
  -     * @param cld ClassDescriptor
        */
  -    private String toSQLClause(InCriteria c, ClassDescriptor cld)
  +    private String toSQLClause(InCriteria c)
       {
           StringBuffer buf = new StringBuffer();
           Collection values = (Collection) c.getValue();
  @@ -495,9 +510,8 @@
        * Answer the SQL-Clause for a SqlCriteria
        *
        * @param c SqlCriteria
  -     * @param cld ClassDescriptor
        */
  -    private String toSQLClause(SqlCriteria c, ClassDescriptor cld)
  +    private String toSQLClause(SqlCriteria c)
       {
           return c.getClause();
       }
  
  
  
  1.7.2.1   +36 -32    db-ojb/src/java/org/apache/ojb/broker/accesslayer/sql/SqlInsertStatement.java
  
  Index: SqlInsertStatement.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/accesslayer/sql/SqlInsertStatement.java,v
  retrieving revision 1.7
  retrieving revision 1.7.2.1
  diff -u -r1.7 -r1.7.2.1
  --- SqlInsertStatement.java	4 Apr 2004 23:53:32 -0000	1.7
  +++ SqlInsertStatement.java	10 Oct 2005 00:02:14 -0000	1.7.2.1
  @@ -30,34 +30,38 @@
    */
   public class SqlInsertStatement extends SqlPkStatement
   {
  +    private String sql;
   
  -	/**
  -	 * Constructor for SqlInsertStatement.
  -	 * @param cld
  -	 * @param logger
  -	 */
  -	public SqlInsertStatement(ClassDescriptor cld, Logger logger)
  -	{
  -		super(cld, logger);
  -	}
  -
  -	/**
  -	 * @see org.apache.ojb.broker.accesslayer.sql.SqlStatement#getStatement()
  -	 */
  -	public String getStatement()
  -	{
  -        StringBuffer stmt = new StringBuffer(1024);
  -        ClassDescriptor cld = getClassDescriptor();
  -
  -        stmt.append("INSERT INTO ");
  -        appendTable(cld, stmt);
  -        stmt.append(" (");
  -        appendListOfColumns(cld, stmt);
  -        stmt.append(")");
  -        appendListOfValues(cld, stmt);
  +    /**
  +     * Constructor for SqlInsertStatement.
  +     *
  +     * @param cld
  +     * @param logger
  +     */
  +    public SqlInsertStatement(ClassDescriptor cld, Logger logger)
  +    {
  +        super(cld, logger);
  +    }
  +
  +    /** @see SqlStatement#getStatement() */
  +    public String getStatement()
  +    {
  +        if(sql == null)
  +        {
  +            StringBuffer stmt = new StringBuffer(1024);
  +            ClassDescriptor cld = getClassDescriptor();
  +
  +            stmt.append("INSERT INTO ");
  +            appendTable(cld, stmt);
  +            stmt.append(" (");
  +            appendListOfColumns(cld, stmt);
  +            stmt.append(")");
  +            appendListOfValues(cld, stmt);
   
  -        return stmt.toString();
  -	}
  +            sql = stmt.toString();
  +        }
  +        return sql;
  +    }
   
       private List appendListOfColumns(ClassDescriptor cld, StringBuffer buf)
       {
  @@ -65,9 +69,9 @@
   
           ArrayList columnList = new ArrayList();
   
  -        for (int i = 0; i < fields.length; i++)
  +        for(int i = 0; i < fields.length; i++)
           {
  -            if (i > 0)
  +            if(i > 0)
               {
                   buf.append(",");
               }
  @@ -86,16 +90,16 @@
       {
           FieldDescriptor[] fields = cld.getAllRwFields();
   
  -        if (fields.length == 0)
  +        if(fields.length == 0)
           {
               return;
           }
   
           stmt.append(" VALUES (");
  -        for (int i = 0; i < fields.length; i++)
  +        for(int i = 0; i < fields.length; i++)
           {
               stmt.append("?");
  -            if (i < fields.length - 1)
  +            if(i < fields.length - 1)
               {
                   stmt.append(",");
               }
  
  
  
  1.5.2.1   +79 -71    db-ojb/src/java/org/apache/ojb/broker/accesslayer/sql/SqlPkStatement.java
  
  Index: SqlPkStatement.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/accesslayer/sql/SqlPkStatement.java,v
  retrieving revision 1.5
  retrieving revision 1.5.2.1
  diff -u -r1.5 -r1.5.2.1
  --- SqlPkStatement.java	4 Apr 2004 23:53:32 -0000	1.5
  +++ SqlPkStatement.java	10 Oct 2005 00:02:14 -0000	1.5.2.1
  @@ -15,6 +15,9 @@
    * limitations under the License.
    */
   
  +import java.lang.ref.WeakReference;
  +
  +import org.apache.ojb.broker.OJBRuntimeException;
   import org.apache.ojb.broker.PersistenceBrokerException;
   import org.apache.ojb.broker.metadata.ClassDescriptor;
   import org.apache.ojb.broker.metadata.FieldDescriptor;
  @@ -22,98 +25,103 @@
   
   /**
    * Model simple Statements based on ClassDescriptor and/or PrimaryKey
  - * 
  + *
    * @author <a href="mailto:jbraeuchi@hotmail.com">Jakob Braeuchi</a>
    * @version $Id$
    */
   public abstract class SqlPkStatement implements SqlStatement
   {
  -    private ClassDescriptor m_classDescriptor;
  +    // arminw: Use weak reference to allow GC of removed metadata instances
  +    private WeakReference m_classDescriptor;
       private Logger m_logger;
   
  -	/**
  -	 * Constructor for SqlPkStatement.
  -	 */
  -	public SqlPkStatement(ClassDescriptor aCld,Logger aLogger)
  -	{
  -		super();
  -        m_classDescriptor = aCld;
  +    /** Constructor for SqlPkStatement. */
  +    public SqlPkStatement(ClassDescriptor aCld, Logger aLogger)
  +    {
  +        super();
  +        m_classDescriptor = new WeakReference(aCld);
           m_logger = aLogger;
  -	}
  +    }
   
  -    /**
  -     * append table name
  -     */
  +    /** append table name */
       protected void appendTable(ClassDescriptor cld, StringBuffer stmt)
       {
           stmt.append(cld.getFullTableName());
       }
   
  -	/**
  -	 * Returns the logger.
  -	 * @return Logger
  -	 */
  -	protected Logger getLogger()
  -	{
  -		return m_logger;
  -	}    
  -    	
  +    /**
  +     * Returns the logger.
  +     *
  +     * @return Logger
  +     */
  +    protected Logger getLogger()
  +    {
  +        return m_logger;
  +    }
  +
       /**
        * Returns the classDescriptor.
  +     *
        * @return ClassDescriptor
        */
       protected ClassDescriptor getClassDescriptor()
       {
  -        return m_classDescriptor;
  +        ClassDescriptor cld = (ClassDescriptor) m_classDescriptor.get();
  +        if(cld == null)
  +        {
  +            throw new OJBRuntimeException("Requested ClassDescriptor instance was already GC by JVM");
  +        }
  +        return cld;
       }
   
  -	/**
  -	 * Generate a sql where-clause for the array of fields
  -	 *
  -	 * @param fields array containing all columns used in WHERE clause
  -	 */
  -	protected void appendWhereClause(FieldDescriptor[] fields, StringBuffer stmt) throws PersistenceBrokerException
  -	{
  -		stmt.append(" WHERE ");
  -
  -		for (int i = 0; i < fields.length; i++)
  -		{
  -			FieldDescriptor fmd = fields[i];
  -
  -			stmt.append(fmd.getColumnName());
  -			stmt.append(" = ? ");
  -			if (i < fields.length - 1)
  -			{
  -				stmt.append(" AND ");
  -			}
  -		}
  -	}
  -    
  -	/**
  -	 * Generate a where clause for a prepared Statement.
  -	 * Only primary key and locking fields are used in this where clause
  -	 * @param cld the ClassDescriptor
  -	 * @param useLocking true if locking fields should be included
  -	 * @param stmt the StatementBuffer
  -	 */
  -	protected void appendWhereClause(ClassDescriptor cld, boolean useLocking, StringBuffer stmt)
  -	{
  -		FieldDescriptor[] pkFields = cld.getPkFields();
  -		FieldDescriptor[] fields;
  -
  -		fields = pkFields;
  -		if (useLocking)
  -		{
  -			FieldDescriptor[] lockingFields = cld.getLockingFields();
  -			if (lockingFields.length > 0)
  -			{
  -				fields = new FieldDescriptor[pkFields.length + lockingFields.length];
  -				System.arraycopy(pkFields, 0, fields, 0, pkFields.length);
  -				System.arraycopy(lockingFields, 0, fields, pkFields.length, lockingFields.length);
  -			}
  -		}
  +    /**
  +     * Generate a sql where-clause for the array of fields
  +     *
  +     * @param fields array containing all columns used in WHERE clause
  +     */
  +    protected void appendWhereClause(FieldDescriptor[] fields, StringBuffer stmt) throws PersistenceBrokerException
  +    {
  +        stmt.append(" WHERE ");
  +
  +        for(int i = 0; i < fields.length; i++)
  +        {
  +            FieldDescriptor fmd = fields[i];
  +
  +            stmt.append(fmd.getColumnName());
  +            stmt.append(" = ? ");
  +            if(i < fields.length - 1)
  +            {
  +                stmt.append(" AND ");
  +            }
  +        }
  +    }
  +
  +    /**
  +     * Generate a where clause for a prepared Statement.
  +     * Only primary key and locking fields are used in this where clause
  +     *
  +     * @param cld the ClassDescriptor
  +     * @param useLocking true if locking fields should be included
  +     * @param stmt the StatementBuffer
  +     */
  +    protected void appendWhereClause(ClassDescriptor cld, boolean useLocking, StringBuffer stmt)
  +    {
  +        FieldDescriptor[] pkFields = cld.getPkFields();
  +        FieldDescriptor[] fields;
   
  -		appendWhereClause(fields, stmt);
  -	}
  +        fields = pkFields;
  +        if(useLocking)
  +        {
  +            FieldDescriptor[] lockingFields = cld.getLockingFields();
  +            if(lockingFields.length > 0)
  +            {
  +                fields = new FieldDescriptor[pkFields.length + lockingFields.length];
  +                System.arraycopy(pkFields, 0, fields, 0, pkFields.length);
  +                System.arraycopy(lockingFields, 0, fields, pkFields.length, lockingFields.length);
  +            }
  +        }
  +
  +        appendWhereClause(fields, stmt);
  +    }
   
   }
  
  
  
  1.8.2.2   +32 -15    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.2.1
  retrieving revision 1.8.2.2
  diff -u -r1.8.2.1 -r1.8.2.2
  --- SqlSelectByPkStatement.java	5 Oct 2005 18:01:26 -0000	1.8.2.1
  +++ SqlSelectByPkStatement.java	10 Oct 2005 00:02:14 -0000	1.8.2.2
  @@ -25,33 +25,50 @@
   
   /**
    * Model a SELECT Statement by Primary Key
  - * 
  + *
    * @author <a href="mailto:jbraeuchi@gmx.ch">Jakob Braeuchi</a>
    * @version $Id$
    */
   
   public class SqlSelectByPkStatement extends SqlSelectStatement
   {
  -	/**
  -	 * Constructor for SqlSelectByPkStatement.
  -	 * @param cld
  -	 * @param logger
  -	 */
  -	public SqlSelectByPkStatement(Platform pf, ClassDescriptor cld, Logger logger)
  -	{        
  +    private String sql;
  +
  +    /**
  +     * Constructor for SqlSelectByPkStatement.
  +     *
  +     * @param cld
  +     * @param logger
  +     */
  +    public SqlSelectByPkStatement(Platform pf, ClassDescriptor cld, Logger logger)
  +    {
           super(pf, cld, buildQuery(cld), logger);
  -	}
  +    }
   
  +    /**
  +     * Build a Pk-Query base on the ClassDescriptor.
  +     *
  +     * @param cld
  +     * @return a select by PK query
  +     */
       private static Query buildQuery(ClassDescriptor cld)
       {
           FieldDescriptor[] pkFields = cld.getPkFields();
           Criteria crit = new Criteria();
  -        
  -        for (int i = 0; i < pkFields.length; i++)
  +
  +        for(int i = 0; i < pkFields.length; i++)
           {
               crit.addEqualTo(pkFields[i].getAttributeName(), null);
           }
  -        Query query = new QueryByCriteria(cld.getClassOfObject(), crit);        
  -        return query;
  +        return new QueryByCriteria(cld.getClassOfObject(), crit);
  +    }
  +
  +    public String getStatement()
  +    {
  +        if(sql == null)
  +        {
  +            sql = super.getStatement();
  +        }
  +        return sql;
       }
  -}
  +}
  \ No newline at end of file
  
  
  
  1.22.2.6  +83 -55    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.5
  retrieving revision 1.22.2.6
  diff -u -r1.22.2.5 -r1.22.2.6
  --- SqlSelectStatement.java	5 Oct 2005 18:01:26 -0000	1.22.2.5
  +++ SqlSelectStatement.java	10 Oct 2005 00:02:14 -0000	1.22.2.6
  @@ -20,6 +20,7 @@
   import java.util.List;
   import java.util.Map;
   import java.util.Set;
  +import java.lang.ref.WeakReference;
   
   import org.apache.commons.collections.set.ListOrderedSet;
   import org.apache.ojb.broker.metadata.ClassDescriptor;
  @@ -42,7 +43,7 @@
    */
   public class SqlSelectStatement extends SqlQueryStatement implements SelectStatement
   {
  -    private FieldDescriptor[] fieldsForSelect;
  +    private WeakReference fieldsForSelect;
   
       /**
        * Constructor for SqlSelectStatement.
  @@ -74,7 +75,7 @@
       /**
        * Append a Column with alias: A0 name -> A0.name
        * @param anAlias the TableAlias
  -     * @param aColumn name
  +     * @param field
        * @param buf
        */
       protected void appendColumn(TableAlias anAlias, FieldDescriptor field, StringBuffer buf)
  @@ -94,9 +95,9 @@
        * @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)
  +    protected List appendListOfColumnsForSelect(StringBuffer buf)
       {
  -        FieldDescriptor[] fieldDescriptors = getFieldsForSelect(cld);
  +        FieldDescriptor[] fieldDescriptors = getFieldsForSelect();
           ArrayList columnList = new ArrayList();
           TableAlias searchAlias = getSearchTable();
           
  @@ -116,32 +117,50 @@
               columnList.add(field.getAttributeName());
           }
           
  -        appendClazzColumnForSelect(cld, buf);
  +        appendClazzColumnForSelect(buf);
           return columnList;
       }
    
       /**
  -     * Create the OJB_CLAZZ pseudo column. This column defines the Class to be instantiated
  +     * Get MultiJoined ClassDescriptors
        * @param cld
  -     * @param buf
        */
  -    private void appendClazzColumnForSelect(ClassDescriptor cld, StringBuffer buf)
  +    private ClassDescriptor[] getMultiJoinedClassDescriptors(ClassDescriptor cld)
       {
           DescriptorRepository repository = cld.getRepository();
           Class[] multiJoinedClasses = repository.getSubClassesMultipleJoinedTables(cld, true);
  +        ClassDescriptor[] result = new ClassDescriptor[multiJoinedClasses.length];
  +
  +        for (int i = 0 ; i < multiJoinedClasses.length; i++)
  +        {
  +            result[i] = repository.getDescriptorFor(multiJoinedClasses[i]);
  +         }
  +
  +        return result;
  +    }
  +
  +    /**
  +     * Create the OJB_CLAZZ pseudo column based on CASE WHEN.
  +     * This column defines the Class to be instantiated.
  +     * @param buf
  +     */
  +    private void appendClazzColumnForSelect(StringBuffer buf)
  +    {
  +        ClassDescriptor cld = getSearchClassDescriptor();
  +        ClassDescriptor[] clds = getMultiJoinedClassDescriptors(cld);
   
  -        if (multiJoinedClasses.length == 0)
  +        if (clds.length == 0)
           {
               return;
           }
           
           buf.append(",CASE");
   
  -        for (int i = multiJoinedClasses.length; i > 0; i--)
  +        for (int i = clds.length; i > 0; i--)
           {
               buf.append(" WHEN ");
   
  -            ClassDescriptor subCld = repository.getDescriptorFor(multiJoinedClasses[i-1]);
  +            ClassDescriptor subCld = clds[i - 1];
               FieldDescriptor[] fieldDescriptors = subCld.getPkFields();
   
               TableAlias alias = getTableAliasForClassDescriptor(subCld);
  @@ -155,15 +174,29 @@
                   appendColumn(alias, field, buf);
                   buf.append(" IS NOT NULL");
               }
  -            buf.append(" THEN '" + subCld.getClassNameOfObject() + "'");
  +            buf.append(" THEN '").append(subCld.getClassNameOfObject()).append("'");
           }
  -        buf.append(" ELSE '" + cld.getClassNameOfObject() + "'");
  +        buf.append(" ELSE '").append(cld.getClassNameOfObject()).append("'");
           buf.append(" END AS " + SqlHelper.OJB_CLASS_COLUMN);
       }
       
       /**
        * Return the Fields to be selected.
        *
  +     * @return the Fields to be selected
  +     */
  +    protected FieldDescriptor[] getFieldsForSelect()
  +    {
  +        if (fieldsForSelect == null || fieldsForSelect.get() == null)
  +        {
  +            fieldsForSelect = new WeakReference(buildFieldsForSelect(getSearchClassDescriptor()));
  +        }
  +        return (FieldDescriptor[]) fieldsForSelect.get();
  +    }
  +
  +    /**
  +     * Return the Fields to be selected.
  +     *
        * @param cld the ClassDescriptor
        * @return the Fields to be selected
        */
  @@ -207,32 +240,6 @@
       }
   
       /**
  -     * 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;
  -    }
  -
  -    /**
        * Appends to the statement a comma separated list of column names.
        *
        * @param columns defines the columns to be selected (for reports)
  @@ -281,7 +288,7 @@
               Criteria havingCrit = query.getHavingCriteria();
               StringBuffer where = new StringBuffer();
               StringBuffer having = new StringBuffer();
  -            List groupByFields = null;
  +            List groupByFields;
   
               // Set correct tree of joins for the current criteria
               setRoot((TableAlias) entry.getKey());
  @@ -319,8 +326,7 @@
                    * will allow us to load objects with unique mapping fields that are mapped
                    * to the same table.
                    */
  -                
  -                columnList.addAll(appendListOfColumnsForSelect(getSearchClassDescriptor(), stmt));
  +                columnList.addAll(appendListOfColumnsForSelect(stmt));
               }
               else
               {
  @@ -353,18 +359,18 @@
                * treeder: going to map superclass tables here,
                * not sure about the columns, just using all columns for now
                */
  -            ClassDescriptor cld = super.getBaseClassDescriptor();
  +            ClassDescriptor cld = getBaseClassDescriptor();
               ClassDescriptor cldSuper = null;
               if (cld.getSuperClass() != null)
               {
                   // then we have a super class so join tables
                   cldSuper = cld.getRepository().getDescriptorFor(cld.getSuperClass());
  -                appendSuperClassColumns(cld, cldSuper, stmt);
  +                appendSuperClassColumns(cldSuper, stmt);
               }
   
               stmt.append(" FROM ");
  -
               appendTableWithJoins(getRoot(), where, stmt);
  +
               if (cld.getSuperClass() != null)
               {
                   appendSuperClassJoin(cld, cldSuper, stmt, where);
  @@ -391,7 +397,9 @@
   */
       private void appendSuperClassJoin(ClassDescriptor cld, ClassDescriptor cldSuper, StringBuffer stmt, StringBuffer where)
       {
  -        stmt.append(",").append(cldSuper.getFullTableName());
  +        stmt.append(",");
  +        appendTable(cldSuper, stmt);
  +
           if (where != null)
           {
               if (where.length() > 0)
  @@ -403,14 +411,18 @@
               // TODO: do not use the superclassfield anymore, just assume that the id is the same in both tables - @see PBroker.storeToDb
               int superFieldRef = cld.getSuperClassFieldRef();
               FieldDescriptor refField = cld.getFieldDescriptorByIndex(superFieldRef);
  -            where.append(cldSuper.getFullTableName()).append(".").append(
  -                    cldSuper.getAutoIncrementFields()[0].getColumnName());
  +
  +            appendTable(cldSuper, where);
  +            where.append(".");
  +            appendField(cldSuper.getAutoIncrementFields()[0], where);
               where.append(" = ");
  -            where.append(cld.getFullTableName()).append(".").append(refField.getColumnName());
  +            appendTable(cld, where);
  +            where.append(".");
  +            appendField(refField, where);
           }
       }
   
  -    private void appendSuperClassColumns(ClassDescriptor cldSub, ClassDescriptor cldSuper, StringBuffer buf)
  +    private void appendSuperClassColumns(ClassDescriptor cldSuper, StringBuffer buf)
       {
           FieldDescriptor[] fields = cldSuper.getFieldDescriptions();
           for (int i = 0; i < fields.length; i++)
  @@ -426,6 +438,22 @@
           }
       }
   
  +    /**
  +     * Append table name. Quote if necessary.
  +     */
  +    protected void appendTable(ClassDescriptor cld, StringBuffer buf)
  +    {
  +        buf.append(cld.getFullTableName());
  +    }
  +
  +    /**
  +     * Append column name. Quote if necessary.
  +     */
  +    protected void appendField(FieldDescriptor fld, StringBuffer buf)
  +    {
  +        buf.append(fld.getColumnName());
  +    }
  +
       public Query getQueryInstance()
       {
           return getQuery();
  @@ -434,11 +462,12 @@
       public int getColumnIndex(FieldDescriptor fld)
       {
           int index = JdbcType.MIN_INT;
  -        if (fieldsForSelect != null)
  +        FieldDescriptor[] fields = getFieldsForSelect();
  +        if (fields != null)
           {
  -            for (int i = 0; i < fieldsForSelect.length; i++)
  +            for (int i = 0; i < fields.length; i++)
               {
  -                if (fieldsForSelect[i].equals(fld))
  +                if (fields[i].equals(fld))
                   {
                       index = i + 1;  // starts at 1
                       break;
  @@ -447,5 +476,4 @@
           }
           return index;
       }
  -
   }
  
  
  
  1.6.2.1   +59 -52    db-ojb/src/java/org/apache/ojb/broker/accesslayer/sql/SqlUpdateStatement.java
  
  Index: SqlUpdateStatement.java
  ===================================================================
  RCS file: /home/cvs/db-ojb/src/java/org/apache/ojb/broker/accesslayer/sql/SqlUpdateStatement.java,v
  retrieving revision 1.6
  retrieving revision 1.6.2.1
  diff -u -r1.6 -r1.6.2.1
  --- SqlUpdateStatement.java	4 Apr 2004 23:53:32 -0000	1.6
  +++ SqlUpdateStatement.java	10 Oct 2005 00:02:14 -0000	1.6.2.1
  @@ -21,62 +21,69 @@
   
   /**
    * Model an UPDATE Statement
  - * 
  + *
    * @author <a href="mailto:jbraeuchi@hotmail.com">Jakob Braeuchi</a>
    * @version $Id$
    */
   public class SqlUpdateStatement extends SqlPkStatement
   {
  +    protected String sql;
   
  -	/**
  -	 * Constructor for SqlUpdateStatement.
  -	 * @param cld
  -	 * @param logger
  -	 */
  -	public SqlUpdateStatement(ClassDescriptor cld, Logger logger)
  -	{
  -		super(cld, logger);
  -	}
  -
  -	/**
  -	 * generates a SET-phrase for a prepared update statement.
  -	 * @param stmt the StringBuffer
  -	 */
  -	private void appendSetClause(ClassDescriptor cld, StringBuffer stmt)
  -	{
  -		FieldDescriptor[] fields = cld.getNonPkRwFields();
  -
  -		if (fields.length == 0)
  -		{
  -			return;
  -		}
  -
  -		stmt.append(" SET ");
  -		for (int i = 0; i < fields.length; i++)
  -		{
  -			stmt.append(fields[i].getColumnName());
  -			stmt.append("=?");
  -			if (i < fields.length - 1)
  -			{
  -				stmt.append(",");
  -			}
  -		}
  -	}
  -
  -	/**
  -	 * @see SqlStatement#getStatement()
  -	 */
  -	public String getStatement()
  -	{
  -		StringBuffer stmt = new StringBuffer(1024);
  -		ClassDescriptor cld = getClassDescriptor();
  -
  -		stmt.append("UPDATE ");
  -		appendTable(cld, stmt);
  -		appendSetClause(cld, stmt);
  -		appendWhereClause(cld, true, stmt); //use Locking
  -
  -		return stmt.toString();
  -	}
  +    /**
  +     * Constructor for SqlUpdateStatement.
  +     *
  +     * @param cld
  +     * @param logger
  +     */
  +    public SqlUpdateStatement(ClassDescriptor cld, Logger logger)
  +    {
  +        super(cld, logger);
  +    }
  +
  +    /**
  +     * generates a SET-phrase for a prepared update statement.
  +     *
  +     * @param stmt the StringBuffer
  +     */
  +    private void appendSetClause(ClassDescriptor cld, StringBuffer stmt)
  +    {
  +        FieldDescriptor[] fields = cld.getNonPkRwFields();
  +
  +        if(fields.length == 0)
  +        {
  +            return;
  +        }
  +
  +        stmt.append(" SET ");
  +        for(int i = 0; i < fields.length; i++)
  +        {
  +            stmt.append(fields[i].getColumnName());
  +            stmt.append("=?");
  +            if(i < fields.length - 1)
  +            {
  +                stmt.append(",");
  +            }
  +        }
  +    }
  +
  +    /**
  +     * @see SqlStatement#getStatement()
  +     */
  +    public String getStatement()
  +    {
  +        if(sql == null)
  +        {
  +            StringBuffer stmt = new StringBuffer(1024);
  +            ClassDescriptor cld = getClassDescriptor();
  +
  +            stmt.append("UPDATE ");
  +            appendTable(cld, stmt);
  +            appendSetClause(cld, stmt);
  +            appendWhereClause(cld, true, stmt); //use Locking
  +
  +            sql = stmt.toString();
  +        }
  +        return sql;
  +    }
   
   }
  
  
  

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