You are viewing a plain text version of this content. The canonical link for it is here.
Posted to torque-dev@db.apache.org by tf...@apache.org on 2011/01/09 14:43:30 UTC

svn commit: r1056930 [1/2] - in /db/torque/torque4/branches/trunk-without-village: torque-runtime/src/main/java/org/apache/torque/adapter/ torque-runtime/src/main/java/org/apache/torque/util/ torque-runtime/src/test/java/org/apache/torque/ torque-runti...

Author: tfischer
Date: Sun Jan  9 13:43:29 2011
New Revision: 1056930

URL: http://svn.apache.org/viewvc?rev=1056930&view=rev
Log:
Use only prepared statements for select statements

Modified:
    db/torque/torque4/branches/trunk-without-village/torque-runtime/src/main/java/org/apache/torque/adapter/DBSybase.java
    db/torque/torque4/branches/trunk-without-village/torque-runtime/src/main/java/org/apache/torque/util/BasePeer.java
    db/torque/torque4/branches/trunk-without-village/torque-runtime/src/main/java/org/apache/torque/util/ColumnValues.java
    db/torque/torque4/branches/trunk-without-village/torque-runtime/src/main/java/org/apache/torque/util/Criteria.java
    db/torque/torque4/branches/trunk-without-village/torque-runtime/src/main/java/org/apache/torque/util/JdbcTypedValue.java
    db/torque/torque4/branches/trunk-without-village/torque-runtime/src/main/java/org/apache/torque/util/JoinBuilder.java
    db/torque/torque4/branches/trunk-without-village/torque-runtime/src/main/java/org/apache/torque/util/LargeSelect.java
    db/torque/torque4/branches/trunk-without-village/torque-runtime/src/main/java/org/apache/torque/util/Query.java
    db/torque/torque4/branches/trunk-without-village/torque-runtime/src/main/java/org/apache/torque/util/SQLBuilder.java
    db/torque/torque4/branches/trunk-without-village/torque-runtime/src/main/java/org/apache/torque/util/SqlExpression.java
    db/torque/torque4/branches/trunk-without-village/torque-runtime/src/test/java/org/apache/torque/BaseTestCase.java
    db/torque/torque4/branches/trunk-without-village/torque-runtime/src/test/java/org/apache/torque/TorqueInstanceTest.java
    db/torque/torque4/branches/trunk-without-village/torque-runtime/src/test/java/org/apache/torque/adapter/DBOracleTest.java
    db/torque/torque4/branches/trunk-without-village/torque-runtime/src/test/java/org/apache/torque/util/CriteriaTest.java
    db/torque/torque4/branches/trunk-without-village/torque-runtime/src/test/java/org/apache/torque/util/QueryTest.java
    db/torque/torque4/branches/trunk-without-village/torque-runtime/src/test/java/org/apache/torque/util/SqlExpressionTest.java
    db/torque/torque4/branches/trunk-without-village/torque-runtime/src/test/resources/Torque.properties
    db/torque/torque4/branches/trunk-without-village/torque-test/src/main/schema/test-schema.xml
    db/torque/torque4/branches/trunk-without-village/torque-test/src/test/java/org/apache/torque/DataTest.java

Modified: db/torque/torque4/branches/trunk-without-village/torque-runtime/src/main/java/org/apache/torque/adapter/DBSybase.java
URL: http://svn.apache.org/viewvc/db/torque/torque4/branches/trunk-without-village/torque-runtime/src/main/java/org/apache/torque/adapter/DBSybase.java?rev=1056930&r1=1056929&r2=1056930&view=diff
==============================================================================
--- db/torque/torque4/branches/trunk-without-village/torque-runtime/src/main/java/org/apache/torque/adapter/DBSybase.java (original)
+++ db/torque/torque4/branches/trunk-without-village/torque-runtime/src/main/java/org/apache/torque/adapter/DBSybase.java Sun Jan  9 13:43:29 2011
@@ -166,7 +166,7 @@ public class DBSybase extends AbstractDB
     public void generateLimits(Query query, int offset, int limit)
         throws TorqueException
     {
-        if ( limit < 0 && offset >= 0 ) // Offset only test
+        if (limit < 0 && offset >= 0) // Offset only test
         {
             return;
         }
@@ -177,7 +177,7 @@ public class DBSybase extends AbstractDB
         else if (limit + offset == 0)
         {
             // This is necessary to create the empty result set that Torque expects
-            query.getWhereClause().add(SqlExpression.build("1", new Integer(0), Criteria.EQUAL));
+            query.getWhereClause().add("1=0");
         }
     }
 

Modified: db/torque/torque4/branches/trunk-without-village/torque-runtime/src/main/java/org/apache/torque/util/BasePeer.java
URL: http://svn.apache.org/viewvc/db/torque/torque4/branches/trunk-without-village/torque-runtime/src/main/java/org/apache/torque/util/BasePeer.java?rev=1056930&r1=1056929&r2=1056930&view=diff
==============================================================================
--- db/torque/torque4/branches/trunk-without-village/torque-runtime/src/main/java/org/apache/torque/util/BasePeer.java (original)
+++ db/torque/torque4/branches/trunk-without-village/torque-runtime/src/main/java/org/apache/torque/util/BasePeer.java Sun Jan  9 13:43:29 2011
@@ -20,6 +20,7 @@ package org.apache.torque.util;
  */
 
 import java.io.Serializable;
+import java.math.BigDecimal;
 import java.sql.Connection;
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
@@ -27,11 +28,8 @@ import java.sql.SQLException;
 import java.sql.Statement;
 import java.sql.Types;
 import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
 
 import org.apache.commons.lang.StringUtils;
 import org.apache.commons.logging.Log;
@@ -268,7 +266,7 @@ public abstract class BasePeer
         Criteria.Criterion criterion
                 = (Criteria.Criterion) criteria.values().iterator().next();
         String tableName = criterion.getTable();
-        if (StringUtils.isEmpty(tableName))
+        if (tableName == null)
         {
             throw new TorqueException("Unqualified column name in criteria");
         }
@@ -330,18 +328,23 @@ public abstract class BasePeer
 //                }
 //            };
 
-        Query sql = createQuery(criteria);
+        Query query = createQuery(criteria);
 
-        sql.setType(Query.Type.DELETE);
-        sql.getFromClause().clear();
-        sql.getFromClause().add(new Query.FromElement(tableName, null, null));
+        query.setType(Query.Type.DELETE);
+        query.getFromClause().clear();
+        query.getFromClause().add(new Query.FromElement(tableName, null, null));
+        String sql = query.toString();
 
         PreparedStatement preparedStatement = null;
         try
         {
-            preparedStatement = connection.prepareStatement(sql.toString());
+            preparedStatement = connection.prepareStatement(sql);
+            setPreparedStatementReplacements(
+                    preparedStatement,
+                    query.getPreparedStatementReplacements(),
+                    0);
             long startTime = System.currentTimeMillis();
-            log.debug("Executing delete " + sql.toString());
+            log.debug("Executing delete " + sql);
 
             int affectedRows = preparedStatement.executeUpdate();
             long queryEndTime = System.currentTimeMillis();
@@ -601,7 +604,11 @@ public abstract class BasePeer
      * @return A simple Key representing the new Id value
      * @throws TorqueException Possible errors get wrapped in here.
      */
-    private static SimpleKey getId(ColumnMap pk, IdGenerator keyGen, Connection con, Object keyInfo)
+    private static SimpleKey getId(
+                ColumnMap pk,
+                IdGenerator keyGen,
+                Connection con,
+                Object keyInfo)
             throws TorqueException
     {
         SimpleKey id = null;
@@ -639,22 +646,8 @@ public abstract class BasePeer
     static String createQueryDisplayString(Criteria criteria)
         throws TorqueException
     {
-        return createQuery(criteria).toString();
-    }
-
-    /**
-     * Method to create an SQL query for actual execution based on values in a
-     * Criteria.
-     *
-     * @param criteria A Criteria.
-     * @return the SQL query for actual execution
-     * @exception TorqueException Trouble creating the query string.
-     */
-    public static String createQueryString(Criteria criteria)
-        throws TorqueException
-    {
-        Query query = createQuery(criteria);
-        return query.toString();
+        Query query = SQLBuilder.buildQuery(criteria);
+        return query.getDisplayString();
     }
 
     /**
@@ -666,15 +659,11 @@ public abstract class BasePeer
      * @return the sql query
      * @exception TorqueException Trouble creating the query string.
      */
+    // TODO: remove and replace occurances with implementation
     static Query createQuery(Criteria criteria)
         throws TorqueException
     {
-        return SQLBuilder.buildQueryClause(criteria, null, new SQLBuilder.QueryCallback() {
-                public String process(Criteria.Criterion criterion, List<Object> params)
-                {
-                    return criterion.toString();
-                }
-            });
+        return SQLBuilder.buildQuery(criteria);
     }
 
     /**
@@ -777,145 +766,6 @@ public abstract class BasePeer
     /**
      * Selects rows from a database an maps them to objects.
      *
-     * @param criteria A Criteria specifying the records to select, not null.
-     * @param mapper The mapper creating the objects from the resultSet,
-     *        not null.
-     * @param defaultTableMap The table map used for the
-     *        unqualified columns in the query, not null.
-     * @param connection the database connection, not null.
-     *
-     * @return The results of the query, not null.
-     *
-     * @throws TorqueException if querying the database fails.
-     */
-    public static <T> List<T> doSelect(
-                Criteria criteria,
-                RecordMapper<T> mapper,
-                TableMap defaultTableMap,
-                Connection connection)
-            throws TorqueException
-    {
-        if (connection == null)
-        {
-            throw new NullPointerException("connection is null");
-        }
-
-        correctBooleans(criteria, defaultTableMap);
-
-        Database database = Torque.getDatabase(criteria.getDbName());
-        String query = createQuery(criteria).toString();
-
-        Statement statement = null;
-        ResultSet resultSet = null;
-        try
-        {
-            statement = connection.createStatement();
-            long startTime = System.currentTimeMillis();
-            log.debug("Executing query " + query);
-
-            resultSet = statement.executeQuery(query.toString());
-            long queryEndTime = System.currentTimeMillis();
-            log.trace("query took " + (queryEndTime - startTime)
-                    + " milliseconds");
-
-            int offset;
-            if (database.getAdapter().supportsNativeOffset())
-            {
-                offset = 0; //database takes care of offset
-            }
-            else
-            {
-                offset = criteria.getOffset();
-            }
-
-            int limit;
-            if (database.getAdapter().supportsNativeLimit())
-            {
-                limit = -1; //database takes care of offset
-            }
-            else
-            {
-                if (database.getAdapter().supportsNativeOffset())
-                {
-                    limit = criteria.getLimit();
-                }
-                else
-                {
-                    if (criteria.getLimit() == -1 )
-                    {
-                        limit = criteria.getLimit();
-                    }
-                    else
-                    {
-                        limit = offset + criteria.getLimit();
-                    }
-                }
-            }
-
-            List<T> result = new ArrayList<T>();
-            int rowNumber = 0;
-            while (resultSet.next())
-            {
-                if (rowNumber < offset)
-                {
-                    rowNumber++;
-                    continue;
-                }
-                if (limit >= 0 && rowNumber >= limit)
-                {
-                    break;
-                }
-
-                T rowResult = mapper.processRow(resultSet, 0);
-                result.add(rowResult);
-
-                rowNumber++;
-            }
-            long mappingEndTime = System.currentTimeMillis();
-            log.trace("mapping took " + (mappingEndTime - queryEndTime)
-                    + " milliseconds");
-
-            if (criteria.isSingleRecord() && result.size() > 1)
-            {
-                throw new TooManyRowsException("Criteria expected single Record and "
-                        + "Multiple Records were selected");
-            }
-            return result;
-        }
-        catch (SQLException e)
-        {
-            throw new TorqueException(e);
-        }
-        finally
-        {
-            if (resultSet != null)
-            {
-                try
-                {
-                    resultSet.close();
-                }
-                catch (SQLException e)
-                {
-                    log.warn("error closing resultSet", e);
-                }
-            }
-            if (statement != null)
-            {
-                try
-                {
-                    statement.close();
-                }
-                catch (SQLException e)
-                {
-                    log.warn("error closing statement", e);
-                }
-            }
-        }
-    }
-
-    /**
-     * Selects rows from a database an maps them to objects.
-     *
      * @param query the SQL Query to execute, not null.
      * @param mapper The mapper creating the objects from the resultSet,
      *        not null.
@@ -1098,7 +948,7 @@ public abstract class BasePeer
 //     * @param updateValues A Criteria object containing values used in
 //     * set clause.
 //     * @param con A Connection.
-//     * 
+//     *
 //     * @return the number of affected rows.
 //     *
 //     * @throws TorqueException Any exceptions caught during processing will be
@@ -1254,7 +1104,7 @@ public abstract class BasePeer
      * <p>
      * "WHERE primary_key_id = someValue"
      * <p>
-     * To perform an update on a table with multiple primary keys or 
+     * To perform an update on a table with multiple primary keys or
      * an update with non-primary key fields in the WHERE
      * clause, use doUpdate(ColumnValues, Criteria).
      *
@@ -1312,7 +1162,7 @@ public abstract class BasePeer
      * <p>
      * "WHERE primary_key_id = someValue"
      * <p>
-     * To perform an update on a table with multiple primary keys or 
+     * To perform an update on a table with multiple primary keys or
      * an update with non-primary key fields in the WHERE
      * clause, use doUpdate(ColumnValues, Criteria, Connection).
      *
@@ -1420,11 +1270,11 @@ public abstract class BasePeer
                 Connection connection)
             throws TorqueException
     {
-        Query sql = createQuery(criteria);
-        sql.setType(Query.Type.UPDATE);
+        Query query = createQuery(criteria);
+        query.setType(Query.Type.UPDATE);
 
         // ignore select columns in criteria
-        sql.getSelectClause().clear();
+        query.getSelectClause().clear();
         List<JdbcTypedValue> replacementObjects
                 = new ArrayList<JdbcTypedValue>();
         for (Map.Entry<String, JdbcTypedValue> updateValue
@@ -1436,14 +1286,14 @@ public abstract class BasePeer
                 columnName = columnName.substring(
                         columnName.lastIndexOf(".") + 1);
             }
-            sql.getSelectClause().add(columnName);
+            query.getSelectClause().add(columnName);
             replacementObjects.add(updateValue.getValue());
         }
 
         PreparedStatement preparedStatement = null;
         try
         {
-            preparedStatement = connection.prepareStatement(sql.toString());
+            preparedStatement = connection.prepareStatement(query.toString());
             int position = 1;
             for (JdbcTypedValue replacementObject : replacementObjects)
             {
@@ -1460,8 +1310,12 @@ public abstract class BasePeer
                 }
                 position++;
             }
+            setPreparedStatementReplacements(
+                    preparedStatement,
+                    query.getPreparedStatementReplacements(),
+                    position - 1);
             long startTime = System.currentTimeMillis();
-            log.debug("Executing update " + sql.toString()
+            log.debug("Executing update " + query.toString()
                     + " using parameters " + replacementObjects);
 
             int affectedRows = preparedStatement.executeUpdate();
@@ -1609,7 +1463,7 @@ public abstract class BasePeer
      * @return The results of the query, not null.
      * @throws TorqueException Error performing database query.
      */
-    public static <T> List<T> doPSSelect(
+    public static <T> List<T> doSelect(
             Criteria criteria,
             RecordMapper<T> mapper,
             TableMap defaultTableMap,
@@ -1618,10 +1472,7 @@ public abstract class BasePeer
     {
         correctBooleans(criteria, defaultTableMap);
 
-        StringBuffer query = new StringBuffer();
-        List<Object> params = new ArrayList<Object>(criteria.size());
-
-        createPreparedStatement(criteria, query, params);
+        Query query = SQLBuilder.buildQuery(criteria);
 
         PreparedStatement statement = null;
         ResultSet resultSet = null;
@@ -1629,30 +1480,15 @@ public abstract class BasePeer
         {
             statement = connection.prepareStatement(query.toString());
 
-            for (int i = 0; i < params.size(); i++)
-            {
-                Object param = params.get(i);
-                if (param instanceof java.sql.Date)
-                {
-                    statement.setDate(i + 1, (java.sql.Date) param);
-                }
-                else if (param instanceof NumberKey)
-                {
-                    statement.setBigDecimal(i + 1,
-                        ((NumberKey) param).getBigDecimal());
-                }
-                else if (param instanceof Integer)
-                {
-                    statement.setInt(i + 1, ((Integer) param).intValue());
-                }
-                else
-                {
-                    statement.setString(i + 1, param.toString());
-                }
-            }
+            setPreparedStatementReplacements(
+                    statement,
+                    query.getPreparedStatementReplacements(),
+                    0);
 
             long startTime = System.currentTimeMillis();
-            log.debug("Executing query " + query + ", parameters = " + params);
+            log.debug("Executing query " + query
+                    + ", parameters = "
+                    + query.getPreparedStatementReplacements());
 
             resultSet = statement.executeQuery();
             long queryEndTime = System.currentTimeMillis();
@@ -1683,7 +1519,7 @@ public abstract class BasePeer
                 }
                 else
                 {
-                    if (criteria.getLimit() == -1 )
+                    if (criteria.getLimit() == -1)
                     {
                         limit = criteria.getLimit();
                     }
@@ -1756,84 +1592,48 @@ public abstract class BasePeer
         }
     }
 
-    /**
-     * Do a Prepared Statement select according to the given criteria.
-     *
-     * @param criteria A Criteria specifying the records to select, not null.
-     * @param mapper The mapper creating the objects from the resultSet,
-     *        not null.
-     * @param defaultTableMap The table map used for the
-     *        unqualified columns in the query, not null.
-     *
-     * @return The results of the query, not null.
-     *
-     * @throws TorqueException if a database error occurs.
-     */
-    public static <T> List<T> doPSSelect(
-                Criteria criteria,
-                RecordMapper<T> mapper,
-                TableMap defaultTableMap)
-            throws TorqueException
+    private static void setPreparedStatementReplacements(
+                PreparedStatement statement, 
+                List<Object> replacements,
+                int offset)
+            throws SQLException
     {
-        Connection connection = null;
-        try
-        {
-            connection = Transaction.beginOptional(
-                    criteria.getDbName(),
-                    criteria.isUseTransaction());
-
-            List<T> result = doPSSelect(
-                    criteria,
-                    mapper,
-                    defaultTableMap,
-                    connection);
-
-            Transaction.commit(connection);
-            connection = null;
-            return result;
-        }
-        finally
+        int i = 1 + offset;
+        for (Object param : replacements)
         {
-            if (connection != null)
+            if (param instanceof java.sql.Date)
             {
-                Transaction.safeRollback(connection);
+                statement.setDate(i, (java.sql.Date) param);
+            }
+            else if (param instanceof NumberKey)
+            {
+                statement.setBigDecimal(i,
+                    ((NumberKey) param).getBigDecimal());
+            }
+            else if (param instanceof Integer)
+            {
+                statement.setInt(i, ((Integer) param).intValue());
+            }
+            else if (param instanceof Long)
+            {
+                statement.setLong(i, ((Long) param).longValue());
+            }
+            else if (param instanceof BigDecimal)
+            {
+                statement.setBigDecimal(i, (BigDecimal) param);
+            }
+            else if (param instanceof Boolean)
+            {
+                statement.setBoolean(i, ((Boolean) param).booleanValue());
+            }
+            else
+            {
+                statement.setString(i, param.toString());
             }
+            ++i;
         }
     }
 
-    /**
-     * Create a new PreparedStatement.  It builds a string representation
-     * of a query and a list of PreparedStatement parameters.
-     *
-     * @param criteria
-     * @param queryString
-     * @param params
-     * @throws TorqueException Any exceptions caught during processing will be
-     *         rethrown wrapped into a TorqueException.
-     */
-    public static void createPreparedStatement(
-        Criteria criteria,
-        StringBuffer queryString,
-        List<Object> params)
-        throws TorqueException
-    {
-        Query query = SQLBuilder.buildQueryClause(
-            criteria, params, new SQLBuilder.QueryCallback() {
-                public String process(
-                        Criteria.Criterion criterion,
-                        List<Object> params)
-                {
-                    StringBuffer sb = new StringBuffer();
-                    criterion.appendPsTo(sb, params);
-                    return sb.toString();
-                }
-            });
-
-        String sql = query.toString();
-        log.debug(sql);
-
-        queryString.append(sql);
-    }
 
     /**
      * Checks all columns in the criteria to see whether
@@ -1854,55 +1654,57 @@ public abstract class BasePeer
             TableMap defaultTableMap)
         throws TorqueException
     {
-        Iterator<?> keyIt = criteria.keySet().iterator();
-        while (keyIt.hasNext())
+        for (Object criterionObject : criteria.values())
+        {
+            Criteria.Criterion criterion = (Criteria.Criterion) criterionObject;
+            correctBooleans(criteria, criterion, defaultTableMap);
+       }
+    }
+
+    private static void correctBooleans(
+                Criteria criteria,
+                Criteria.Criterion criterion,
+                TableMap defaultTableMap)
+            throws TorqueException
+    {
+        String tableName = criterion.getTable();
+        TableMap tableMap = null;
+        if (tableName != null)
         {
-            String key = (String) keyIt.next();
-            String columnName;
-            TableMap tableMap = null;
-            int dotPosition = key.lastIndexOf(".");
-            if (dotPosition == -1)
+            String databaseName = criteria.getDbName();
+            if (databaseName == null)
             {
-                columnName = key;
-                tableMap = defaultTableMap;
+                databaseName = Torque.getDefaultDB();
             }
-            else
+            DatabaseMap databaseMap = Torque.getDatabaseMap(databaseName);
+            if (databaseMap != null)
             {
-                columnName = key.substring(dotPosition + 1);
-                String tableName = key.substring(0, dotPosition);
-                String databaseName = criteria.getDbName();
-                if (databaseName == null)
-                {
-                    databaseName = Torque.getDefaultDB();
-                }
-                DatabaseMap databaseMap = Torque.getDatabaseMap(databaseName);
-                if (databaseMap != null)
-                {
-                    tableMap = databaseMap.getTable(tableName);
-                }
-                if (tableMap == null)
-                {
-                    // try aliases
-                    Map<String, String> aliases = criteria.getAliases();
-                    if (aliases.get(tableName) != null)
-                    {
-                        tableName = aliases.get(tableName);
-                        tableMap = databaseMap.getTable(tableName);
-                    }
-                }
+                tableMap = databaseMap.getTable(tableName);
             }
             if (tableMap == null)
             {
-                // no description of table available, do not modify anything
-                continue;
+                // try aliases
+                Map<String, String> aliases = criteria.getAliases();
+                if (aliases.get(tableName) != null)
+                {
+                    tableName = aliases.get(tableName);
+                    tableMap = databaseMap.getTable(tableName);
+                }
             }
-
+        }
+        if (tableMap == null)
+        {
+            tableMap = defaultTableMap;
+        }
+        // if no description of table available, do not modify anything
+        if (tableMap != null)
+        {
+            String columnName = criterion.getColumn();
             ColumnMap columnMap = tableMap.getColumn(columnName);
             if (columnMap != null)
             {
                 if ("BOOLEANINT".equals(columnMap.getTorqueType()))
                 {
-                    Criteria.Criterion criterion = criteria.getCriterion(key);
                     replaceBooleanValues(
                             criterion,
                             new Integer(1),
@@ -1910,11 +1712,15 @@ public abstract class BasePeer
                 }
                 else if ("BOOLEANCHAR".equals(columnMap.getTorqueType()))
                 {
-                    Criteria.Criterion criterion = criteria.getCriterion(key);
                     replaceBooleanValues(criterion, "Y", "N");
                  }
             }
         }
+
+        for (Criteria.Criterion attachedCriterion : criterion.getClauses())
+        {
+            correctBooleans(criteria, attachedCriterion, defaultTableMap);
+        }
     }
 
     /**

Modified: db/torque/torque4/branches/trunk-without-village/torque-runtime/src/main/java/org/apache/torque/util/ColumnValues.java
URL: http://svn.apache.org/viewvc/db/torque/torque4/branches/trunk-without-village/torque-runtime/src/main/java/org/apache/torque/util/ColumnValues.java?rev=1056930&r1=1056929&r2=1056930&view=diff
==============================================================================
--- db/torque/torque4/branches/trunk-without-village/torque-runtime/src/main/java/org/apache/torque/util/ColumnValues.java (original)
+++ db/torque/torque4/branches/trunk-without-village/torque-runtime/src/main/java/org/apache/torque/util/ColumnValues.java Sun Jan  9 13:43:29 2011
@@ -26,24 +26,6 @@ import java.util.Set;
 
 import org.apache.torque.map.TableMap;
 
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
 /**
  * A class containing values for database columns.
  *
@@ -162,7 +144,7 @@ public class ColumnValues implements Map
     @Override
     public String toString()
     {
-        return "ColumnValues [table=" + table 
+        return "ColumnValues [table=" + table
             + ", columnValues=" + columnValues + "]";
     }
 

Modified: db/torque/torque4/branches/trunk-without-village/torque-runtime/src/main/java/org/apache/torque/util/Criteria.java
URL: http://svn.apache.org/viewvc/db/torque/torque4/branches/trunk-without-village/torque-runtime/src/main/java/org/apache/torque/util/Criteria.java?rev=1056930&r1=1056929&r2=1056930&view=diff
==============================================================================
--- db/torque/torque4/branches/trunk-without-village/torque-runtime/src/main/java/org/apache/torque/util/Criteria.java (original)
+++ db/torque/torque4/branches/trunk-without-village/torque-runtime/src/main/java/org/apache/torque/util/Criteria.java Sun Jan  9 13:43:29 2011
@@ -27,6 +27,7 @@ import java.lang.reflect.Array;
 import java.math.BigDecimal;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.GregorianCalendar;
 import java.util.HashMap;
 import java.util.Hashtable;
@@ -168,12 +169,16 @@ public class Criteria extends Hashtable
 
     private Criterion having = null;
 
-    /** Maps column alias names to the real column names. */
+    /**
+     * Maps column alias names to the real column names.
+     * The key of the map is the alias and the value is the real name
+     * of the column.
+     */
     private Map<String, String> asColumns
             = new LinkedHashMap<String, String>();
 
     /** Contains all joins. */
-    private transient List<Join> joins = new ArrayList(3);
+    private transient List<Join> joins = new ArrayList<Join>();
 
     /** The name of the database. */
     private String dbName;
@@ -470,12 +475,7 @@ public class Criteria extends Hashtable
      */
     public Criteria add(Criterion c)
     {
-        StringBuffer sb = new StringBuffer(c.getTable().length()
-                + c.getColumn().length() + 1);
-        sb.append(c.getTable());
-        sb.append('.');
-        sb.append(c.getColumn());
-        super.put(sb.toString(), c);
+        super.put(c.getFullyQualifiedColumnName(), c);
         return this;
     }
 
@@ -1286,12 +1286,12 @@ public class Criteria extends Hashtable
      * @param year An int with the year.
      * @param month An int with the month. Month value is 0-based.
      *        e.g., 0 for January
-     * @param date An int with the date.
+     * @param day An int with the day.
      * @return A modified Criteria object.
      */
-    public Criteria addDate(String column, int year, int month, int date)
+    public Criteria addDate(String column, int year, int month, int day)
     {
-        add(column, new GregorianCalendar(year, month, date).getTime());
+        add(column, new GregorianCalendar(year, month, day).getTime());
         return this;
     }
 
@@ -1949,7 +1949,7 @@ public class Criteria extends Hashtable
      */
     public Criteria and(Criterion c)
     {
-        Criterion oc = getCriterion(c.getTable() + '.' + c.getColumn());
+        Criterion oc = getCriterion(c.getFullyQualifiedColumnName());
 
         if (oc == null)
         {
@@ -2515,7 +2515,7 @@ public class Criteria extends Hashtable
      */
     public Criteria or(Criterion c)
     {
-        Criterion oc = getCriterion(c.getTable() + '.' + c.getColumn());
+        Criterion oc = getCriterion(c.getFullyQualifiedColumnName());
 
         if (oc == null)
         {
@@ -3193,7 +3193,7 @@ public class Criteria extends Hashtable
         Criterion(String table, String column, Object val, SqlEnum comp)
         {
             this(val, comp);
-            this.table = (table == null ? "" : table);
+            this.table = table;
             this.column = (column == null ? "" : column);
         }
 
@@ -3211,7 +3211,7 @@ public class Criteria extends Hashtable
             int dot = tableColumn.lastIndexOf('.');
             if (dot == -1)
             {
-                table = "";
+                table = null;
                 column = tableColumn;
             }
             else
@@ -3256,19 +3256,39 @@ public class Criteria extends Hashtable
         }
 
         /**
+         * Returns the fully qualified name of the criterion's column.
+         *
+         * @return the fully qualified column name.
+         */
+        public String getFullyQualifiedColumnName()
+        {
+            if (table == null)
+            {
+                return column;
+            }
+            return table + "." + column;
+        }
+
+        /**
          * Set the table name.
          *
          * @param name A String with the table name.
          */
         public void setTable(String name)
         {
+            if ("".equals(name))
+            {
+                throw new IllegalArgumentException(
+                        "table name not be empty (use null instead)");
+            }
             this.table = name;
         }
 
         /**
          * Get the table name.
          *
-         * @return A String with the table name.
+         * @return A String with the table name, or null if the criteria
+         *         refers to an unqualified column.
          */
         public String getTable()
         {
@@ -3377,19 +3397,23 @@ public class Criteria extends Hashtable
         }
 
         /**
-         *  get the list of clauses in this Criterion
+         * Returns the list of clauses in this Criterion.
+         *
+         * @return an unmodifiable list of the clauses, not null.
          */
-        private List<Criterion> getClauses()
+        public List<Criterion> getClauses()
         {
-            return clauses;
+            return Collections.unmodifiableList(clauses);
         }
 
         /**
-         *  get the list of conjunctions in this Criterion
+         * Returns the list of conjunctions in this Criterion
+         *
+         * @return an unmodifiable list of the conjunctions, not null.
          */
-        private List<String> getConjunctions()
+        public List<String> getConjunctions()
         {
-            return conjunctions;
+            return Collections.unmodifiableList(conjunctions);
         }
 
         /**
@@ -3447,13 +3471,12 @@ public class Criteria extends Hashtable
                 }
                 else
                 {
-                    field = new StringBuffer(
+                    field = new StringBuilder(
                             table.length() + 1 + column.length())
                             .append(table).append('.').append(column)
                             .toString();
                 }
-                SqlExpression.build(field, value, comparison,
-                        ignoreStringCase || ignoreCase, getDb(), sb);
+                sb.append(field).append(comparison).append(value);
             }
 
             for (int i = 0; i < this.clauses.size(); i++)
@@ -3466,121 +3489,6 @@ public class Criteria extends Hashtable
         }
 
         /**
-         * Appends a Prepared Statement representation of the Criterion
-         * onto the buffer.
-         *
-         * @param sb The stringbuffer that will receive the Prepared Statement
-         * @param params A list to which Prepared Statement parameters
-         * will be appended
-         */
-        public void appendPsTo(StringBuffer sb, List<Object> params)
-        {
-            if (column == null || value == null)
-            {
-                return;
-            }
-
-            DB db = getDb();
-
-            for (int j = 0; j < this.clauses.size(); j++)
-            {
-                sb.append('(');
-            }
-            if (CUSTOM == comparison)
-            {
-                if (!"".equals(value))
-                {
-                    sb.append((String) value);
-                }
-            }
-            else
-            {
-                String field = null;
-                if (table == null)
-                {
-                    field = column;
-                }
-                else
-                {
-                    field = new StringBuffer(
-                            table.length() + 1 + column.length())
-                            .append(table).append('.').append(column)
-                            .toString();
-                }
-
-                if (comparison.equals(Criteria.IN)
-                        || comparison.equals(Criteria.NOT_IN))
-                {
-                    sb.append(field)
-                            .append(comparison);
-
-                    UniqueList<String> inClause = new UniqueList<String>();
-
-                    if (value instanceof List)
-                    {
-                        value = ((List<?>) value).toArray (new Object[0]);
-                    }
-
-                    for (int i = 0; i < Array.getLength(value); i++)
-                    {
-                        Object item = Array.get(value, i);
-
-                        inClause.add(SqlExpression.processInValue(item,
-                                             ignoreStringCase || ignoreCase,
-                                             db));
-                    }
-
-                    StringBuffer inString = new StringBuffer();
-                    inString.append('(').append(StringUtils.join(
-                                                        inClause.iterator(), (","))).append(')');
-                    sb.append(inString.toString());
-                }
-                else
-                {
-                    if (ignoreStringCase || ignoreCase)
-                    {
-                        sb.append(db.ignoreCase(field))
-                                .append(comparison)
-                                .append(db.ignoreCase("?"));
-                    }
-                    else
-                    {
-                        sb.append(field)
-                                .append(comparison)
-                                .append(" ? ");
-                    }
-
-                    if (value instanceof java.util.Date)
-                    {
-                        params.add(new java.sql.Date(
-                                           ((java.util.Date) value).getTime()));
-                    }
-                    else if (value instanceof DateKey)
-                    {
-                        params.add(new java.sql.Date(
-                                           ((DateKey) value).getDate().getTime()));
-                    }
-                    else if (value instanceof Integer)
-                    {
-                        params.add(value);
-                    }
-                    else
-                    {
-                        params.add(value.toString());
-                    }
-                }
-            }
-
-            for (int i = 0; i < this.clauses.size(); i++)
-            {
-                sb.append(this.conjunctions.get(i));
-                Criterion clause = this.clauses.get(i);
-                clause.appendPsTo(sb, params);
-                sb.append(')');
-            }
-        }
-
-        /**
          * Build a string representation of the Criterion.
          *
          * @return A String with the representation of the Criterion.
@@ -3708,7 +3616,10 @@ public class Criteria extends Hashtable
         {
             if (c != null)
             {
-                s.add(c.getTable());
+                if (c.getTable() != null)
+                {
+                    s.add(c.getTable());
+                }
                 for (int i = 0; i < c.getClauses().size(); i++)
                 {
                     addCriterionTable((Criterion) (c.getClauses().get(i)), s);

Modified: db/torque/torque4/branches/trunk-without-village/torque-runtime/src/main/java/org/apache/torque/util/JdbcTypedValue.java
URL: http://svn.apache.org/viewvc/db/torque/torque4/branches/trunk-without-village/torque-runtime/src/main/java/org/apache/torque/util/JdbcTypedValue.java?rev=1056930&r1=1056929&r2=1056930&view=diff
==============================================================================
--- db/torque/torque4/branches/trunk-without-village/torque-runtime/src/main/java/org/apache/torque/util/JdbcTypedValue.java (original)
+++ db/torque/torque4/branches/trunk-without-village/torque-runtime/src/main/java/org/apache/torque/util/JdbcTypedValue.java Sun Jan  9 13:43:29 2011
@@ -1,7 +1,5 @@
 package org.apache.torque.util;
 
-import java.sql.Types;
-
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file

Modified: db/torque/torque4/branches/trunk-without-village/torque-runtime/src/main/java/org/apache/torque/util/JoinBuilder.java
URL: http://svn.apache.org/viewvc/db/torque/torque4/branches/trunk-without-village/torque-runtime/src/main/java/org/apache/torque/util/JoinBuilder.java?rev=1056930&r1=1056929&r2=1056930&view=diff
==============================================================================
--- db/torque/torque4/branches/trunk-without-village/torque-runtime/src/main/java/org/apache/torque/util/JoinBuilder.java (original)
+++ db/torque/torque4/branches/trunk-without-village/torque-runtime/src/main/java/org/apache/torque/util/JoinBuilder.java Sun Jan  9 13:43:29 2011
@@ -47,7 +47,8 @@ public final class JoinBuilder
     }
 
     /**
-     * adds the Joins from the criteria to the query
+     * Adds the Joins from the criteria to the query.
+     *
      * @param criteria the criteria from which the Joins are taken
      * @param query the query to which the Joins should be added
      * @throws TorqueException if the Joins can not be processed
@@ -104,17 +105,6 @@ public final class JoinBuilder
                 dbTableName = rightTableName;
             }
 
-            String columnName = rightColumn.substring(
-                    dot + 1,
-                    rightColumn.length());
-
-            boolean ignoreCase = (criteria.isIgnoreCase()
-                    && (dbMap
-                            .getTable(dbTableName)
-                            .getColumn(columnName)
-                            .getType()
-                            instanceof String));
-
             rightTableName = SQLBuilder.getTableNameForFromClause(
                     rightTableName, criteria);
 
@@ -145,8 +135,7 @@ public final class JoinBuilder
                     queryFromClause.add(fromElement);
                 }
                 queryWhereClause.add(
-                        SqlExpression.buildInnerJoin(
-                                leftColumn, rightColumn, ignoreCase, db));
+                        buildInnerJoin(leftColumn, rightColumn));
             }
             else
             {
@@ -171,9 +160,8 @@ public final class JoinBuilder
                     Query.FromElement fromElement
                             = new Query.FromElement(
                                     rightTableName, joinType,
-                                    SqlExpression.buildInnerJoin(
-                                            leftColumn, rightColumn,
-                                            ignoreCase, db));
+                                    buildInnerJoin(
+                                            leftColumn, rightColumn));
                     queryFromClause.add(fromElement);
                 }
                 else
@@ -197,9 +185,8 @@ public final class JoinBuilder
                     Query.FromElement fromElement
                             = new Query.FromElement(
                                     leftTableName, reverseJoinType(joinType),
-                                    SqlExpression.buildInnerJoin(
-                                            rightColumn, leftColumn,
-                                            ignoreCase, db));
+                                    buildInnerJoin(
+                                            rightColumn, leftColumn));
                     queryFromClause.add(fromElement);
                 }
             }
@@ -207,15 +194,17 @@ public final class JoinBuilder
     }
 
     /**
-     * returns the reversed Join type, i.e. the join type which would produce
+     * Returns the reversed Join type, i.e. the join type which would produce
      * the same result if also the joined tables were exchanged:
      * Example:<br />
      * table_a left join table_b <br />
      * produces the same result as  <br />
      * table_b right join table_a<br />
-     * So "left join" is the reverse of "right join"
-     * @param joinType the join type to be reversed
-     * @return the reversed join type
+     * So "left join" is the reverse of "right join".
+     *
+     * @param joinType the join type to be reversed.
+     *
+     * @return the reversed join type.
      */
     private static SqlEnum reverseJoinType(final SqlEnum joinType)
     {
@@ -232,4 +221,18 @@ public final class JoinBuilder
             return joinType;
         }
     }
+
+    /**
+     * Used to specify a join on two columns.
+     *
+     * @param column A column in one of the tables to be joined.
+     * @param relatedColumn The column in the other table to be joined.
+
+     * @return A join expression, e.g. table_a.column_a=table_b.column_b.
+     */
+    private static String buildInnerJoin(String column,
+                                         String relatedColumn)
+    {
+        return column + '=' + relatedColumn;
+    }
 }

Modified: db/torque/torque4/branches/trunk-without-village/torque-runtime/src/main/java/org/apache/torque/util/LargeSelect.java
URL: http://svn.apache.org/viewvc/db/torque/torque4/branches/trunk-without-village/torque-runtime/src/main/java/org/apache/torque/util/LargeSelect.java?rev=1056930&r1=1056929&r2=1056930&view=diff
==============================================================================
--- db/torque/torque4/branches/trunk-without-village/torque-runtime/src/main/java/org/apache/torque/util/LargeSelect.java (original)
+++ db/torque/torque4/branches/trunk-without-village/torque-runtime/src/main/java/org/apache/torque/util/LargeSelect.java Sun Jan  9 13:43:29 2011
@@ -632,7 +632,7 @@ public class LargeSelect<T> implements R
              */
             BasePeer.correctBooleans(criteria, null);
 
-            String query = BasePeer.createQueryString(criteria);
+            String query = BasePeer.createQuery(criteria).toString();
 
             // Get a connection to the db.
             conn = Torque.getConnection(dbName);

Modified: db/torque/torque4/branches/trunk-without-village/torque-runtime/src/main/java/org/apache/torque/util/Query.java
URL: http://svn.apache.org/viewvc/db/torque/torque4/branches/trunk-without-village/torque-runtime/src/main/java/org/apache/torque/util/Query.java?rev=1056930&r1=1056929&r2=1056930&view=diff
==============================================================================
--- db/torque/torque4/branches/trunk-without-village/torque-runtime/src/main/java/org/apache/torque/util/Query.java (original)
+++ db/torque/torque4/branches/trunk-without-village/torque-runtime/src/main/java/org/apache/torque/util/Query.java Sun Jan  9 13:43:29 2011
@@ -19,16 +19,19 @@ package org.apache.torque.util;
  * under the License.
  */
 
+import java.util.ArrayList;
 import java.util.Iterator;
+import java.util.List;
 
 import org.apache.commons.lang.StringUtils;
+import org.apache.torque.TorqueException;
 
 /**
- * Used to assemble an SQL SELECT query.  Attributes exist for the
- * sections of a SELECT: modifiers, columns, from clause, where
- * clause, and order by clause.  The various parts of the query are
- * appended to buffers which only accept unique entries.  This class
- * is used primarily by BasePeer.
+ * Contains the various parts of a SQL statement (select, update or delete).
+ * Attributes exist for the sections of these statements:
+ * modifiers, columns, from clause, where clause, and order by clause.
+ * Most parts of the query are appended to buffers which only accept
+ * unique entries.
  *
  * @author <a href="mailto:jmcnally@collab.net">John D. McNally</a>
  * @author <a href="mailto:sam@neurogrid.com">Sam Joseph</a>
@@ -40,36 +43,111 @@ import org.apache.commons.lang.StringUti
  */
 public class Query
 {
-    public enum Type { SELECT, UPDATE, DELETE };
+    /** All types of the statement. */
+    public enum Type
+    {
+        /** The instance contains the parts of a select statement. */
+        SELECT,
+        /** The instance contains the parts of an update statement. */
+        UPDATE,
+        /** The instance contains the parts of a delete statement. */
+        DELETE
+    };
+
+    /** Constant for text "SELECT ". */
     private static final String SELECT = "SELECT ";
+    /** Constant for text "UPDATE ". */
     private static final String UPDATE = "UPDATE ";
+    /** Constant for text "DELETE FROM ". */
     private static final String DELETE_FROM = "DELETE FROM ";
+    /** Constant for text " FROM ". */
     private static final String FROM = " FROM ";
+    /** Constant for text " SET ". */
     private static final String SET = " SET ";
+    /** Constant for text " WHERE ". */
     private static final String WHERE = " WHERE ";
+    /** Constant for text " AND ". */
     private static final String AND = " AND ";
+    /** Constant for text " ORDER BY ". */
     private static final String ORDER_BY = " ORDER BY ";
+    /** Constant for text " GROUP BY ". */
     private static final String GROUP_BY = " GROUP BY ";
+    /** Constant for text " HAVING ". */
     private static final String HAVING = " HAVING ";
+    /** Constant for text " LIMIT ". */
     private static final String LIMIT = " LIMIT ";
+    /** Constant for text " OFFSET ". */
     private static final String OFFSET = " OFFSET ";
-    private static final String ROWCOUNT = " SET ROWCOUNT ";
+    /** Constant for text " SET ROWCOUNT ". */
+    private static final String SET_ROWCOUNT = " SET ROWCOUNT ";
 
-    // TODO rename to columns
-    private UniqueList<String> updateColumns = new UniqueList<String>();
+    /**
+     * The select modifiers. E.g. DISTINCT.
+     */
     private UniqueList<String> selectModifiers = new UniqueList<String>();
-    private UniqueList<String> selectColumns = new UniqueList<String>();
-    // TODO rename to tables
-    private UniqueList<FromElement> fromTables = new UniqueList<FromElement>();
-    private UniqueList<String> whereCriteria = new UniqueList<String>();
+
+    /**
+     * The select columns for a select statement, or the columns to update
+     * for an update statement.
+     */
+
+    private UniqueList<String> columns = new UniqueList<String>();
+    /**
+     * The tables to select from (including join operators) for
+     * a select clause, or the tables to update or delete for update
+     * or delete statements.
+     */
+    private UniqueList<FromElement> tables = new UniqueList<FromElement>();
+
+    /**
+     * The where clause identifying the rows to select/update/delete.
+     */
+    private UniqueList<String> whereClause = new UniqueList<String>();
+
+    /**
+     * Contains all replacement objects which are inserted into the prepared
+     * statement ? placeholders.
+     */
+    private List<Object> preparedStatementReplacements
+            = new ArrayList<Object>();
+
+    /** The order by columns, possibly including direction (ASC or DESC). */
     private UniqueList<String> orderByColumns = new UniqueList<String>();
+
+    /**  The group by columns. */
     private UniqueList<String> groupByColumns = new UniqueList<String>();
+
+    /** The having clause, or null for none. */
     private String having;
+
+    /** The limit clause, or null for none. */
     private String limit;
+
+    /**
+     * Some databases need a clause to wrap the statement in for limit;
+     * This field contains the starting part of the clause.
+     * Null if the clause is not wanted.
+     */
     private String preLimit;
+
+    /**
+     * Some databases need a clause to wrap the statement in for limit;
+     * This field contains the end part of the clause.
+     * Null if the clause is not wanted.
+     */
     private String postLimit;
+
+    /**
+     * The offset clause, or null for none.
+     */
     private String offset;
+
+    /**
+     * The set rowcount clause, or null for none.
+     */
     private String rowcount;
+
+    /** The type of the statement. */
     private Type type = Type.SELECT;
 
     /**
@@ -84,16 +162,6 @@ public class Query
     }
 
     /**
-     * Set the modifiers. E.g. DISTINCT and ALL.
-     *
-     * @param modifiers the modifiers
-     */
-    public void setSelectModifiers(UniqueList<String> modifiers)
-    {
-        selectModifiers = modifiers;
-    }
-
-    /**
      * Retrieve the columns buffer in order to specify which columns
      * are returned in this query.
      *
@@ -101,27 +169,7 @@ public class Query
      */
     public UniqueList<String> getSelectClause()
     {
-        return selectColumns;
-    }
-
-    /**
-     * Set the columns which are returned by this query.
-     *
-     * @param columns the columns list, not null.
-     */
-    public void setSelectClause(UniqueList<String> columns)
-    {
-        selectColumns = columns;
-    }
-
-    /**
-     * Returns the columns which are updated by this query.
-     *
-     * @return An UniqueList which can used to add columns to be updated.
-     */
-    public UniqueList<String> getUpdateColumns()
-    {
-        return updateColumns;
+        return columns;
     }
 
     /**
@@ -132,39 +180,32 @@ public class Query
      */
     public UniqueList<FromElement> getFromClause()
     {
-        return fromTables;
-    }
-
-    /**
-     * Set the from clause.
-     *
-     * @param tables the tables
-     */
-    public void setFromClause(UniqueList<FromElement> tables)
-    {
-        fromTables = tables;
+        return tables;
     }
 
     /**
      * Retrieve the where buffer in order to specify the selection
-     * criteria E.g. column_a=3.  Expressions added to the buffer will
+     * criteria E.g. column_a=?.  Expressions added to the buffer will
      * be separated using AND.
      *
      * @return An UniqueList used to add selection criteria.
      */
     public UniqueList<String> getWhereClause()
     {
-        return whereCriteria;
+        return whereClause;
     }
 
     /**
-     * Set the where clause.
+     * Retrieves the replacements which are inserted into prepared statement
+     * placeholders. The number and order of the elements in the list
+     * must correspond to the order of the placeholders in the query string.
      *
-     * @param where where clause
+     * @return A List containing all the replacements for the prepared
+     *         statement placeholders, not null.
      */
-    public void setWhereClause(UniqueList<String> where)
+    public List<Object> getPreparedStatementReplacements()
     {
-        whereCriteria = where;
+        return preparedStatementReplacements;
     }
 
     /**
@@ -190,6 +231,17 @@ public class Query
     }
 
     /**
+     * Get the having clause.  This is used to restrict which
+     * rows are returned based on some condition.
+     *
+     * @return A String that is the having clause.
+     */
+    public String getHaving()
+    {
+        return having;
+    }
+
+    /**
      * Set the having clause.  This is used to restrict which rows
      * are returned.
      *
@@ -201,6 +253,17 @@ public class Query
     }
 
     /**
+     * Get the limit number.  This is used to limit the number of
+     * returned by a query in Postgres.
+     *
+     * @return A String with the limit.
+     */
+    public String getLimit()
+    {
+        return limit;
+    }
+
+    /**
      * Set the limit number.  This is used to limit the number of rows
      * returned by a query.
      *
@@ -215,99 +278,88 @@ public class Query
      * Get the Pre limit String. Oracle and DB2 want to encapsulate
      * a query into a subquery for limiting.
      *
-     * @param preLimit A String with the preLimit.
+     * @return A String with the preLimit.
      */
-    public void setPreLimit(String preLimit)
+    public String getPreLimit()
     {
-        this.preLimit = preLimit;
+        return preLimit;
     }
 
     /**
-     * Set the Post limit String. Oracle and DB2 want to encapsulate
+     * Get the Pre limit String. Oracle and DB2 want to encapsulate
      * a query into a subquery for limiting.
      *
-     * @param postLimit A String with the postLimit.
-     */
-    public void setPostLimit(String postLimit)
-    {
-        this.postLimit = postLimit;
-    }
-
-    /**
-     * Set the offset number.  This is used to set the row where the
-     * resultset starts.
-     *
-     * @param offset A String.
+     * @param preLimit A String with the preLimit.
      */
-    public void setOffset(String offset)
+    public void setPreLimit(String preLimit)
     {
-        this.offset = offset;
+        this.preLimit = preLimit;
     }
 
     /**
-     * Set the rowcount number.  This is used to limit the number of
-     * rows returned by Sybase and MS SQL/Server.
+     * Get the Post limit String. Oracle and DB2 want to encapsulate
+     * a query into a subquery for limiting.
      *
-     * @param rowcount A String.
+     * @return A String with the preLimit.
      */
-    public void setRowcount(String rowcount)
+    public String getPostLimit()
     {
-        this.rowcount = rowcount;
+        return postLimit;
     }
 
     /**
-     * Get the having clause.  This is used to restrict which
-     * rows are returned based on some condition.
+     * Set the Post limit String. Oracle and DB2 want to encapsulate
+     * a query into a subquery for limiting.
      *
-     * @return A String that is the having clause.
+     * @param postLimit A String with the postLimit.
      */
-    public String getHaving()
+    public void setPostLimit(String postLimit)
     {
-        return having;
+        this.postLimit = postLimit;
     }
 
     /**
-     * Get the limit number.  This is used to limit the number of
-     * returned by a query in Postgres.
+     * Get the offset number.  This is used to set the row where the
+     * resultset starts.
      *
-     * @return A String with the limit.
+     * @return A String with the offset, or null if no offset is set.
      */
-    public String getLimit()
+    public String getOffset()
     {
-        return limit;
+        return offset;
     }
 
     /**
-     * Get the Post limit String. Oracle and DB2 want to encapsulate
-     * a query into a subquery for limiting.
+     * Set the offset number.  This is used to set the row where the
+     * resultset starts.
      *
-     * @return A String with the preLimit.
+     * @param offset A String.
      */
-    public String getPostLimit()
+    public void setOffset(String offset)
     {
-        return postLimit;
+        this.offset = offset;
     }
 
     /**
-     * Get the Pre limit String. Oracle and DB2 want to encapsulate
-     * a query into a subquery for limiting.
+     * Get the rowcount number.  This is used to limit the number of
+     * returned by a query in Sybase and MS SQL/Server.
      *
-     * @return A String with the preLimit.
+     * @return A String with the row count.
      */
-    public String getPreLimit()
+    public String getRowcount()
     {
-        return preLimit;
+        return rowcount;
     }
 
     /**
-     * Get the offset number.  This is used to set the row where the
-     * resultset starts.
+     * Set the rowcount number.  This is used to limit the number of
+     * rows returned by Sybase and MS SQL/Server.
      *
-     * @return A String with the offset, or null if no offset is set.
+     * @param rowcount A String.
      */
-    public String getOffset()
+    public void setRowcount(String rowcount)
     {
-        return offset;
+        this.rowcount = rowcount;
     }
 
     /**
@@ -323,14 +375,13 @@ public class Query
     }
 
     /**
-     * Get the rowcount number.  This is used to limit the number of
-     * returned by a query in Sybase and MS SQL/Server.
+     * Returns the type of this SQL statement.
      *
-     * @return A String with the row count.
+     * @return type the new type, not null.
      */
-    public String getRowcount()
+    public Type getType()
     {
-        return rowcount;
+        return type;
     }
 
     /**
@@ -350,119 +401,143 @@ public class Query
     }
 
     /**
-     * Returns the type of this SQL statement.
-     *
-     * @return type the new type, not null.
-     */
-    public Type getType()
-    {
-        return type;
-    }
-
-    /**
      * Outputs the query statement.
      *
      * @return A String with the query statement.
      */
     public String toString()
     {
-        return toStringBuffer(new StringBuffer()).toString();
+        return toStringBuilder(new StringBuilder()).toString();
     }
 
-    public StringBuffer toStringBuffer(StringBuffer stmt)
+    /**
+     * Appends the query to a string builder.
+     *
+     * @param stringBuilder the stringBuilder to append to, not null.
+     *
+     * @return the modified passed in string builder.
+     */
+    public StringBuilder toStringBuilder(StringBuilder stringBuilder)
     {
         if (preLimit != null)
         {
-            stmt.append(preLimit);
+            stringBuilder.append(preLimit);
         }
 
         if (rowcount != null)
         {
-            stmt.append(ROWCOUNT)
+            stringBuilder.append(SET_ROWCOUNT)
                 .append(rowcount)
                 .append(" ");
         }
 
         if (Type.SELECT == type)
         {
-            stmt.append(SELECT)
+            stringBuilder.append(SELECT)
                 .append(StringUtils.join(selectModifiers.iterator(), " "))
-                .append(StringUtils.join(selectColumns.iterator(), ", "))
+                .append(StringUtils.join(columns.iterator(), ", "))
                 .append(FROM);
         }
         else if (Type.UPDATE == type)
         {
-            stmt.append(UPDATE);
+            stringBuilder.append(UPDATE);
         }
         else if (Type.DELETE == type)
         {
-            stmt.append(DELETE_FROM);
+            stringBuilder.append(DELETE_FROM);
         }
 
         boolean first = true;
-        for (Iterator<FromElement> it = fromTables.iterator(); it.hasNext();)
+        for (Iterator<FromElement> it = tables.iterator(); it.hasNext();)
         {
             FromElement fromElement = it.next();
 
             if (!first && fromElement.getJoinCondition() == null)
             {
-                stmt.append(", ");
+                stringBuilder.append(", ");
             }
             first = false;
-            stmt.append(fromElement.toString());
+            stringBuilder.append(fromElement.toString());
         }
 
         if (Type.UPDATE == type)
         {
-            stmt.append(SET)
-                .append(StringUtils.join(selectColumns, "=?, "));
-            if (!selectColumns.isEmpty())
+            stringBuilder.append(SET)
+                .append(StringUtils.join(columns, "=?, "));
+            if (!columns.isEmpty())
             {
-                stmt.append("=?");
+                stringBuilder.append("=?");
             }
         }
 
-        if (!whereCriteria.isEmpty())
+        if (!whereClause.isEmpty())
         {
-            stmt.append(WHERE)
-                .append(StringUtils.join(whereCriteria.iterator(), AND));
+            stringBuilder.append(WHERE)
+                .append(StringUtils.join(whereClause.iterator(), AND));
         }
         if (!groupByColumns.isEmpty())
         {
-            stmt.append(GROUP_BY)
+            stringBuilder.append(GROUP_BY)
                 .append(StringUtils.join(groupByColumns.iterator(), ", "));
         }
         if (having != null)
         {
-            stmt.append(HAVING)
+            stringBuilder.append(HAVING)
                 .append(having);
         }
         if (!orderByColumns.isEmpty())
         {
-            stmt.append(ORDER_BY)
+            stringBuilder.append(ORDER_BY)
                 .append(StringUtils.join(orderByColumns.iterator(), ", "));
         }
         if (limit != null)
         {
-            stmt.append(LIMIT)
+            stringBuilder.append(LIMIT)
                 .append(limit);
         }
         if (offset != null)
         {
-            stmt.append(OFFSET)
+            stringBuilder.append(OFFSET)
                 .append(offset);
         }
         if (rowcount != null)
         {
-            stmt.append(ROWCOUNT)
+            stringBuilder.append(SET_ROWCOUNT)
                 .append("0");
         }
         if (postLimit != null)
         {
-            stmt.append(postLimit);
+            stringBuilder.append(postLimit);
         }
 
-        return stmt;
+        return stringBuilder;
+    }
+
+    /**
+     * Returns a String to display this query.
+     *
+     * @return the SQL query for display.
+     *
+     * @exception TorqueException Trouble creating the query string.
+     */
+    public String getDisplayString()
+        throws TorqueException
+    {
+        StringBuilder stringBuilder = new StringBuilder();
+        toStringBuilder(stringBuilder);
+        stringBuilder.append(" Replacements: [");
+        boolean first = true;
+        for (Object replacement : preparedStatementReplacements)
+        {
+            if (!first)
+            {
+                stringBuilder.append(",");
+            }
+            stringBuilder.append(replacement);
+            first = false;
+        }
+        stringBuilder.append("]");
+        return stringBuilder.toString();
     }
 
     /**
@@ -476,13 +551,13 @@ public class Query
     public static class FromElement
     {
 
-        /** the tablename, might contain an appended alias name */
+        /** The tablename, might contain an appended alias name */
         private String tableName = null;
 
-        /** the type of the join, e.g. SqlEnum.LEFT_JOIN */
+        /** The type of the join, e.g. SqlEnum.LEFT_JOIN */
         private SqlEnum joinType = null;
 
-        /** the join condition, e.g. table_a.id = table_b.a_id */
+        /** The join condition, e.g. table_a.id = table_b.a_id */
         private String joinCondition = null;
 
         /**

Modified: db/torque/torque4/branches/trunk-without-village/torque-runtime/src/main/java/org/apache/torque/util/SQLBuilder.java
URL: http://svn.apache.org/viewvc/db/torque/torque4/branches/trunk-without-village/torque-runtime/src/main/java/org/apache/torque/util/SQLBuilder.java?rev=1056930&r1=1056929&r2=1056930&view=diff
==============================================================================
--- db/torque/torque4/branches/trunk-without-village/torque-runtime/src/main/java/org/apache/torque/util/SQLBuilder.java (original)
+++ db/torque/torque4/branches/trunk-without-village/torque-runtime/src/main/java/org/apache/torque/util/SQLBuilder.java Sun Jan  9 13:43:29 2011
@@ -19,11 +19,8 @@ package org.apache.torque.util;
  * under the License.
  */
 
-import java.util.HashSet;
 import java.util.Iterator;
-import java.util.List;
 import java.util.Map;
-import java.util.Set;
 
 import org.apache.commons.lang.StringUtils;
 import org.apache.commons.logging.Log;
@@ -56,7 +53,7 @@ public final class SQLBuilder
     /**
      * Private constructor to prevent instantiation.
      *
-     * Class contains only static method ans should therefore not be
+     * Class contains only static method and should therefore not be
      * instantiated.
      */
     private SQLBuilder()
@@ -180,8 +177,9 @@ public final class SQLBuilder
     }
 
     /**
-     * Returns a table name from an identifier. Each identifier is to be qualified
-     * as [schema.]table.column. This could also contain FUNCTION([schema.]table.column).
+     * Returns a table name from an identifier. Each identifier is
+     * to be qualified as [schema.]table.column.
+     * This could also contain FUNCTION([schema.]table.column).
      *
      * @param name The (possible fully qualified) identifier name
      *
@@ -220,106 +218,52 @@ public final class SQLBuilder
     }
 
 
-
-    /**
-     * Returns a set of all tables and possible aliases referenced
-     * from a criterion. The resulting Set can be directly used to
-     * build a WHERE clause
-     *
-     * @param crit A Criteria object
-     * @param tableCallback A Callback Object
-     * @return A Set of tables.
-     */
-    public static Set<String> getTableSet(
-            final Criteria crit,
-            final TableCallback tableCallback)
-    {
-        Set<String> tables = new HashSet<String>();
-
-        // Loop over all the Criterions
-        for (Iterator<?> it = crit.keySet().iterator(); it.hasNext();)
-        {
-            String key = (String) it.next();
-            Criteria.Criterion c = crit.getCriterion(key);
-            List<String> tableNames = c.getAllTables();
-
-            // Loop over all Tables referenced in this criterion.
-            for (String name : tableNames)
-            {
-                String aliasName = crit.getTableForAlias(name);
-
-                // If the tables have an alias, add an "<xxx> AS <yyy> statement"
-                if (StringUtils.isNotEmpty(aliasName))
-                {
-                    String newName =
-                            new StringBuffer(name.length() + aliasName.length() + 4)
-                            .append(aliasName)
-                            .append(" AS ")
-                            .append(name)
-                            .toString();
-                    name = newName;
-                }
-                tables.add(name);
-            }
-
-            if (tableCallback != null)
-            {
-                tableCallback.process(tables, key, crit);
-            }
-        }
-
-        return tables;
-    }
-
     /**
-     * Builds a Query clause for Updating and deleting
+     * Builds a Query from a criteria.
+     *
+     * @param crit the criteria to build the query from, not null.
+     *
+     * @return the corresponding query to the criteria.
      *
-     * @param crit a <code>Criteria</code> value
-     * @param params a <code>List</code> value
-     * @param qc a <code>QueryCallback</code> value
-     * @return a <code>Query</code> value
      * @exception TorqueException if an error occurs
      */
-    public static Query buildQueryClause(final Criteria crit,
-            final List<Object> params,
-            final QueryCallback qc)
+    public static Query buildQuery(final Criteria crit)
             throws TorqueException
     {
-        Query query = new Query();
+        Query sqlStatement = new Query();
 
         final String dbName = crit.getDbName();
         final DB db = Torque.getDB(dbName);
         final DatabaseMap dbMap = Torque.getDatabaseMap(dbName);
 
-        JoinBuilder.processJoins(db, dbMap, crit, query);
-        processModifiers(crit, query);
-        processSelectColumns(crit, query, dbName);
-        processAsColumns(crit, query);
-        processCriterions(db, dbMap, dbName, crit, query,  params, qc);
-        processGroupBy(crit, query);
-        processHaving(crit, query);
-        processOrderBy(db, dbMap, crit, query);
-        processLimits(crit, query);
+        JoinBuilder.processJoins(db, dbMap, crit, sqlStatement);
+        processModifiers(crit, sqlStatement);
+        processSelectColumns(crit, sqlStatement, dbName);
+        processAsColumns(crit, sqlStatement, dbName);
+        processCriterions(db, dbMap, crit, sqlStatement);
+        processGroupBy(crit, sqlStatement);
+        processHaving(crit, sqlStatement);
+        processOrderBy(db, dbMap, crit, sqlStatement);
+        processLimits(crit, sqlStatement);
 
-        if (log.isDebugEnabled())
-        {
-            log.debug(query.toString());
-        }
-        return query;
+        return sqlStatement;
     }
 
 
     /**
-     * adds the select columns from the criteria to the query
-     * @param criteria the criteria from which the select columns are taken
-     * @param query the query to which the select columns should be added
-     * @throws TorqueException if the select columns can not be processed
+     * Adds the select columns from the criteria to the query.
+     *
+     * @param criteria the criteria from which the select columns are taken.
+     * @param query the query to which the select columns should be added.
+     * @param dbName the name of the database to use.
+     * 
+     * @throws TorqueException if the select columns can not be processed.
      */
     private static void processSelectColumns(
-            final Criteria criteria,
-            final Query query,
-            final String dbName)
-        throws TorqueException
+                final Criteria criteria,
+                final Query query,
+                final String dbName)
+            throws TorqueException
     {
         UniqueList<String> selectClause = query.getSelectClause();
         UniqueList<String> select = criteria.getSelectColumns();
@@ -327,38 +271,53 @@ public final class SQLBuilder
         for (String identifier : select)
         {
             selectClause.add(identifier);
-            addTableToFromClause(getTableName(identifier, dbName), criteria, query);
+            addTableToFromClause(
+                    getTableName(identifier, dbName),
+                    criteria,
+                    query);
         }
     }
 
     /**
-     * adds the As-columns from the criteria to the query.
-     * @param criteria the criteria from which the As-columns are taken
-     * @param query the query to which the As-columns should be added
+     * Adds the As-columns (Aliases for columns) from the criteria
+     * to the query's select clause.
+     *
+     * @param criteria the criteria from which the As-columns are taken,
+     *        not null.
+     * @param query the query to which the As-columns should be added,
+     *        not null.
+     * @param dbName the name of the database to use.
+     *
+     * @throws TorqueException if the as columns can not be processed.
      */
     private static void processAsColumns(
-            final Criteria criteria,
-            final Query query)
+                final Criteria criteria,
+                final Query query,
+                final String dbName)
+            throws TorqueException
     {
         UniqueList<String> querySelectClause = query.getSelectClause();
         Map<String, String> criteriaAsColumns = criteria.getAsColumns();
 
         for (Map.Entry<String, String> entry : criteriaAsColumns.entrySet())
         {
-            String key = entry.getKey();
+            String identifier = entry.getValue();
             querySelectClause.add(
-                    new StringBuffer()
-                    .append(entry.getValue())
-                    .append(SqlEnum.AS)
-                    .append(key)
-                    .toString());
+                    identifier + SqlEnum.AS + entry.getKey());
+            addTableToFromClause(
+                    getTableName(identifier, dbName),
+                    criteria,
+                    query);
         }
     }
 
     /**
-     * adds the Modifiers from the criteria to the query
-     * @param criteria the criteria from which the Modifiers are taken
-     * @param query the query to which the Modifiers should be added
+     * Adds the select modifiers from the criteria to the query.
+     *
+     * @param criteria the criteria from which the Modifiers are taken,
+     *        not null.
+     * @param query the query to which the Modifiers should be added,
+     *        not null.
      */
     private static void processModifiers(
             final Criteria criteria,
@@ -373,60 +332,111 @@ public final class SQLBuilder
     }
 
     /**
-     * adds the Criterion-objects from the criteria to the query
+     * Adds the Criterions from the criteria to the query.
+     *
+     * @param db the database for which the query should be created.
+     * @param dbMap the database map for the database in which the query
+     *        should run.
      * @param criteria the criteria from which the Criterion-objects are taken
-     * @param query the query to which the Criterion-objects should be added
-     * @param params the parameters if a prepared statement should be built,
-     *        or null if a normal statement should be built.
+     * @param query the query to which the Criterion-objects should be added.
+     *
      * @throws TorqueException if the Criterion-objects can not be processed
      */
     private static void processCriterions(
             final DB db,
             final DatabaseMap dbMap,
-            final String dbName,
-            final Criteria crit,
-            final Query query,
-            final List<Object> params,
-            final QueryCallback qc)
+            final Criteria criteria,
+            final Query query)
         throws TorqueException
     {
         UniqueList<String> whereClause = query.getWhereClause();
 
-        for (Iterator<?> it = crit.keySet().iterator(); it.hasNext();)
+        for (Iterator<?> it = criteria.keySet().iterator(); it.hasNext();)
         {
             String key = (String) it.next();
-            Criteria.Criterion criterion = crit.getCriterion(key);
-            Criteria.Criterion[] someCriteria =
-                    criterion.getAttachedCriterion();
+            Criteria.Criterion criterion = criteria.getCriterion(key);
 
-            String table = null;
-            for (int i = 0; i < someCriteria.length; i++)
-            {
-                String tableName = someCriteria[i].getTable();
+            StringBuilder sb = new StringBuilder();
+            appendCriterionToPs(
+                    criterion,
+                    criteria,
+                    sb,
+                    db,
+                    dbMap,
+                    query);
+            whereClause.add(sb.toString());
+        }
+    }
 
+    private static void appendCriterionToPs(
+                Criterion criterion,
+                Criteria criteria,
+                StringBuilder sb,
+                DB db,
+                DatabaseMap databaseMap,
+                Query query)
+            throws TorqueException
+    {
+        {
+            criterion.setDB(db);
+            String tableName = criterion.getTable();
+
+            if (tableName != null)
+            {
                 // add the table to the from clause, if it is not already
                 // contained there
                 // it is important that this piece of code is executed AFTER
                 // the joins are processed
-                addTableToFromClause(getFullTableName(tableName, dbName), crit, query);
-
-                table = crit.getTableForAlias(tableName);
-                if (table == null)
-                {
-                    table = tableName;
-                }
-
-                boolean ignoreCase =  ((crit.isIgnoreCase() || someCriteria[i].isIgnoreCase())
-                        && (dbMap.getTable(table)
-                                .getColumn(someCriteria[i].getColumn())
-                                .getType()
-                                instanceof String));
+                addTableToFromClause(getFullTableName(
+                        tableName,
+                        databaseMap.getName()),
+                        criteria,
+                        query);
+            }
 
-                someCriteria[i].setIgnoreCase(ignoreCase);
+            String table = criteria.getTableForAlias(tableName);
+            if (table == null)
+            {
+                table = tableName;
             }
 
-            criterion.setDB(db);
-            whereClause.add(qc.process(criterion, params));
+            boolean ignoreCase
+                = ((criteria.isIgnoreCase()
+                        || criterion.isIgnoreCase())
+                    && (databaseMap.getTable(table)
+                            .getColumn(criterion.getColumn())
+                            .getType()
+                        instanceof String));
+
+            criterion.setIgnoreCase(ignoreCase);
+        }
+
+        for (int j = 0; j < criterion.getClauses().size(); j++)
+        {
+            sb.append('(');
+        }
+        String columnName = criterion.getFullyQualifiedColumnName();
+        SqlExpression.buildPs(
+                columnName,
+                criterion.getValue(),
+                criterion.getComparison(),
+                criterion.isIgnoreCase() || criteria.isIgnoreCase(),
+                criterion.getDb(),
+                sb,
+                query.getPreparedStatementReplacements());
+
+        for (int i = 0; i < criterion.getClauses().size(); i++)
+        {
+            sb.append(criterion.getConjunctions().get(i));
+            Criterion clause = criterion.getClauses().get(i);
+            appendCriterionToPs(
+                    clause,
+                    criteria,
+                    sb,
+                    db,
+                    databaseMap,
+                    query);
+            sb.append(')');
         }
     }
 
@@ -699,7 +709,7 @@ public final class SQLBuilder
             // true is returned.
             return true;
         }
-        for (Query.FromElement fromElement :  fromClause)
+        for (Query.FromElement fromElement : fromClause)
         {
             if (tableName.equals(fromElement.getTableName()))
             {
@@ -710,13 +720,15 @@ public final class SQLBuilder
     }
 
     /**
-     * adds a table to the from clause of a query, if it is not already
+     * Adds a table to the from clause of a query, if it is not already
      * contained there.
+     *
      * @param tableOrAliasName the name of a table
      *        or the alias for a table
      * @param criteria a criteria object to resolve a possible alias
      * @param query the query where the the tablename should be added
      *        to the from clause
+     *
      * @return the table in the from clause which represents the
      *         supplied tableOrAliasName
      */
@@ -743,37 +755,4 @@ public final class SQLBuilder
         }
         return tableNameForFromClause;
     }
-
-    /**
-     * Inner Interface that defines the Callback method for
-     * the Table creation loop.
-     */
-    public interface TableCallback
-    {
-        /**
-         * Callback Method for getTableSet()
-         *
-         * @param tables The current table name
-         * @param key The current criterion key.
-         * @param crit The Criteria used in getTableSet()
-         */
-        void process(Set<String> tables, String key, Criteria crit);
-    }
-
-    /**
-     * Inner Interface that defines the Callback method for
-     * the buildQuery Criterion evaluation
-     */
-    public interface QueryCallback
-    {
-        /**
-         * The callback for building a query String
-         *
-         * @param criterion The current criterion
-         * @param params The parameter list passed to buildQueryString()
-         * @return WHERE SQL fragment for this criterion
-         */
-        String process(Criterion criterion, List<Object> params);
-    }
-
 }



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