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