Author: tfischer
Date: Sat Sep 5 02:18:04 2015
New Revision: 1701342
URL: http://svn.apache.org/r1701342
Log:
TORQUE-306 Use named variables for replacements
Added:
db/torque/torque4/trunk/torque-test/src/test/java/org/apache/torque/generated/peer/ExecuteStatementsTest.java
Modified:
db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/util/BasePeerImpl.java
db/torque/torque4/trunk/torque-runtime/src/test/java/org/apache/torque/util/BasePeerImplTest.java
db/torque/torque4/trunk/torque-templates/src/main/resources/org/apache/torque/templates/om/templates/peer/base/executeStatement.vm
db/torque/torque4/trunk/torque-templates/src/main/resources/org/apache/torque/templates/om/templates/peer/base/imports.vm
Modified:
db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/util/BasePeerImpl.java
URL:
http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/util/BasePeerImpl.java?rev=1701342&r1=1701341&r2=1701342&view=diff
==============================================================================
---
db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/util/BasePeerImpl.java
(original)
+++
db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/util/BasePeerImpl.java
Sat Sep 5 02:18:04 2015
@@ -30,6 +30,8 @@ import java.sql.Types;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
@@ -1640,7 +1642,7 @@ public class BasePeerImpl<T> implements
*/
public int executeStatement(final String statementString) throws
TorqueException
{
- return executeStatement(statementString, Torque.getDefaultDB(), null);
+ return executeStatement(statementString, Torque.getDefaultDB(),
(List<JdbcTypedValue>) null);
}
/**
@@ -1784,6 +1786,145 @@ public class BasePeerImpl<T> implements
}
/**
+ * Utility method which executes a given sql statement
+ * as prepared statement.
+ * This method should be used for update, insert, and delete statements.
+ * Use executeQuery() for selects.
+ *
+ * @param statementString A String with the sql statement to execute,
+ * containing placeholders of the form ":${placeholderName}".
+ * ${placeholderName} must contain only letters, digits and the
underscore
+ * Each placeholder must be followed by a space, except when it is
at the end of the statement.
+ * @param replacementValues a map mapping the placeholder names to values
+ * to use as placeholders in the query.
+ * Can be null or empty if no placeholders need to be filled.
+ *
+ * @return The number of rows affected.
+ *
+ * @throws TorqueException if executing the statement fails.
+ */
+ public int executeStatement(
+ final String statementString,
+ final Map<String, JdbcTypedValue> replacementValues)
+ throws TorqueException
+ {
+ return executeStatement(
+ statementString,
+ Torque.getDefaultDB(),
+ replacementValues);
+ }
+
+ /**
+ * Utility method which executes a given sql statement
+ * as prepared statement.
+ * This method should be used for update, insert, and delete statements.
+ * Use executeQuery() for selects.
+ *
+ * @param statementString A String with the sql statement to execute,
+ * containing placeholders of the form ":${placeholderName}".
+ * ${placeholderName} must contain only letters, digits and the
underscore
+ * Each placeholder must be followed by a space, except when it is
at the end of the statement.
+ * @param dbName The name of the database to execute the statement against,
+ * or null for the default DB.
+ * @param replacementValues a map mapping the placeholder names to values
+ * to use as placeholders in the query.
+ * Can be null or empty if no placeholders need to be filled.
+ *
+ * @return The number of rows affected.
+ *
+ * @throws TorqueException if executing the statement fails.
+ */
+ public int executeStatement(
+ final String statementString,
+ final String dbName,
+ final Map<String, JdbcTypedValue> replacementValues)
+ throws TorqueException
+ {
+ Connection con = null;
+ try
+ {
+ con = Transaction.begin(dbName);
+ int rowCount = executeStatement(
+ statementString,
+ con,
+ replacementValues);
+ Transaction.commit(con);
+ con = null;
+ return rowCount;
+ }
+ finally
+ {
+ if (con != null)
+ {
+ Transaction.safeRollback(con);
+ }
+ }
+ }
+
+ /**
+ * Utility method which executes a given sql statement
+ * as prepared statement.
+ * This method should be used for update, insert, and delete statements.
+ * Use executeQuery() for selects.
+ *
+ * @param statementString A String with the sql statement to execute,
+ * containing placeholders of the form ":${placeholderName}".
+ * ${placeholderName} must contain only letters, digits and the
underscore
+ * Each placeholder must be followed by a space, except when it is
at the end of the statement.
+ * @param con The database connection to use.
+ * @param replacementValues a map mapping the placeholder names (without
leading colons)
+ * to values to use as placeholders in the query.
+ * Can be null or empty if no placeholders need to be filled.
+ *
+ * @return The number of rows affected.
+ *
+ * @throws TorqueException if executing the statement fails.
+ */
+ public int executeStatement(
+ final String statementString,
+ final Connection con,
+ final Map<String, JdbcTypedValue> replacementValues)
+ throws TorqueException
+ {
+ StringBuilder changedStatement = new StringBuilder();
+ List<JdbcTypedValue> replacementValueList = new
ArrayList<JdbcTypedValue>();
+ Pattern pattern = Pattern.compile(":(\\w+)(?: |$)");
+ Matcher matcher = pattern.matcher(statementString);
+ int statementPosition = 0;
+ while (matcher.find())
+ {
+ int groupStart = matcher.start();
+ if (groupStart > statementPosition)
+ {
+
changedStatement.append(statementString.substring(statementPosition,
groupStart));
+ }
+ String group = matcher.group();
+ String key = group.substring(1);
+ String replacement = "?";
+ if (key.endsWith(" "))
+ {
+ key = key.substring(0, key.length() - 1);
+ replacement += " ";
+ }
+ if (replacementValues != null &&
replacementValues.containsKey(key))
+ {
+ changedStatement.append(replacement);
+ replacementValueList.add(replacementValues.get(key));
+ }
+ else
+ {
+ changedStatement.append(group);
+ }
+ statementPosition = matcher.end();
+ }
+ if (statementPosition != statementString.length() - 1)
+ {
+
changedStatement.append(statementString.substring(statementPosition));
+ }
+ return executeStatement(changedStatement.toString(), con,
replacementValueList);
+ }
+
+ /**
* Sets the prepared statement replacements into a query, possibly
* modifying the type if required by DB Drivers.
*
Modified:
db/torque/torque4/trunk/torque-runtime/src/test/java/org/apache/torque/util/BasePeerImplTest.java
URL:
http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-runtime/src/test/java/org/apache/torque/util/BasePeerImplTest.java?rev=1701342&r1=1701341&r2=1701342&view=diff
==============================================================================
---
db/torque/torque4/trunk/torque-runtime/src/test/java/org/apache/torque/util/BasePeerImplTest.java
(original)
+++
db/torque/torque4/trunk/torque-runtime/src/test/java/org/apache/torque/util/BasePeerImplTest.java
Sat Sep 5 02:18:04 2015
@@ -31,7 +31,9 @@ import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import org.apache.torque.BaseTestCase;
import org.apache.torque.Column;
@@ -600,4 +602,52 @@ public class BasePeerImplTest extends Ba
assertEquals(1, result);
}
+
+ /**
+ * Check that executeStatements with a set of named replacements works.
+ *
+ * @throws Exception if the test fails.
+ */
+ public void testExecuteStatementNamed() throws Exception
+ {
+ Map<String, JdbcTypedValue> replacementValues = new HashMap<String,
JdbcTypedValue>();
+ replacementValues.put("key1", new JdbcTypedValue(1, 1));
+ replacementValues.put("key3", new JdbcTypedValue("3", 3));
+
+ basePeerImpl.executeStatement("SELECT * from TABLE WHERE Column1=:key1
AND COLUMN2=:notExistingKey AND COLUMN3=:key3",
+ replacementValues);
+
+ // verify mock (verification order not relevant)
+ verify(connection).prepareStatement(
+ "SELECT * from TABLE WHERE Column1=? AND
COLUMN2=:notExistingKey AND COLUMN3=?");
+ verify(preparedStatement).setObject(1, 1, 1);
+ verify(preparedStatement).setObject(2, "3", 3);
+ verify(preparedStatement).executeUpdate();
+ verify(preparedStatement).close();
+ verify(transactionManager).begin("postgresql");
+ verify(transactionManager).commit(connection);
+ verifyNoMoreInteractions(connection, preparedStatement,
transactionManager);
+ }
+
+ /**
+ * Check that executeStatements with a set of named replacements works
when the statement contains no replacements.
+ *
+ * @throws Exception if the test fails.
+ */
+ public void testExecuteStatementNamedNoReplacements() throws Exception
+ {
+ Map<String, JdbcTypedValue> replacementValues = new HashMap<String,
JdbcTypedValue>();
+ replacementValues.put("key1", new JdbcTypedValue(null, 42));
+ replacementValues.put("unusedKey", new JdbcTypedValue("3", 3));
+
+ basePeerImpl.executeStatement("SELECT * from TABLE",
replacementValues);
+
+ // verify mock (verification order not relevant)
+ verify(connection).prepareStatement("SELECT * from TABLE");
+ verify(preparedStatement).executeUpdate();
+ verify(preparedStatement).close();
+ verify(transactionManager).begin("postgresql");
+ verify(transactionManager).commit(connection);
+ verifyNoMoreInteractions(connection, preparedStatement,
transactionManager);
+ }
}
Modified:
db/torque/torque4/trunk/torque-templates/src/main/resources/org/apache/torque/templates/om/templates/peer/base/executeStatement.vm
URL:
http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-templates/src/main/resources/org/apache/torque/templates/om/templates/peer/base/executeStatement.vm?rev=1701342&r1=1701341&r2=1701342&view=diff
==============================================================================
---
db/torque/torque4/trunk/torque-templates/src/main/resources/org/apache/torque/templates/om/templates/peer/base/executeStatement.vm
(original)
+++
db/torque/torque4/trunk/torque-templates/src/main/resources/org/apache/torque/templates/om/templates/peer/base/executeStatement.vm
Sat Sep 5 02:18:04 2015
@@ -126,3 +126,96 @@
con,
replacementValues);
}
+
+ /**
+ * Utility method which executes a given sql statement
+ * as prepared statement.
+ * This method should be used for update, insert, and delete statements.
+ * Use executeQuery() for selects.
+ *
+ * @param statementString A String with the sql statement to execute,
+ * containing placeholders of the form ":${placeholderName}".
+ * ${placeholderName} must contain only letters, digits and the
underscore
+ * Each placeholder must be followed by a space, except when it is
at the end of the statement.
+ * @param replacementValues a map mapping the placeholder names to values
+ * to use as placeholders in the query.
+ * Can be null or empty if no placeholders need to be filled.
+ *
+ * @return The number of rows affected.
+ *
+ * @throws TorqueException if executing the statement fails.
+ */
+ public static int executeStatement(
+ final String statementString,
+ final Map<String, JdbcTypedValue> replacementValues)
+ throws TorqueException
+ {
+ return ${peerImplGetter}().executeStatement(
+ statementString,
+ replacementValues);
+ }
+
+ /**
+ * Utility method which executes a given sql statement
+ * as prepared statement.
+ * This method should be used for update, insert, and delete statements.
+ * Use executeQuery() for selects.
+ *
+ * @param statementString A String with the sql statement to execute,
+ * containing placeholders of the form ":${placeholderName}".
+ * ${placeholderName} must contain only letters, digits and the
underscore
+ * Each placeholder must be followed by a space, except when it is
at the end of the statement.
+ * @param dbName The name of the database to execute the statement against,
+ * or null for the default DB.
+ * @param replacementValues a map mapping the placeholder names to values
+ * to use as placeholders in the query.
+ * Can be null or empty if no placeholders need to be filled.
+ *
+ * @return The number of rows affected.
+ *
+ * @throws TorqueException if executing the statement fails.
+ */
+ public static int executeStatement(
+ final String statementString,
+ final String dbName,
+ final Map<String, JdbcTypedValue> replacementValues)
+ throws TorqueException
+ {
+ return ${peerImplGetter}().executeStatement(
+ statementString,
+ dbName,
+ replacementValues);
+ }
+
+ /**
+ * Utility method which executes a given sql statement
+ * as prepared statement.
+ * This method should be used for update, insert, and delete statements.
+ * Use executeQuery() for selects.
+ *
+ * @param statementString A String with the sql statement to execute,
+ * containing placeholders of the form ":${placeholderName}".
+ * ${placeholderName} must contain only letters, digits and the
underscore
+ * Each placeholder must be followed by a space, except when it is
at the end of the statement.
+ * @param con The database connection to use.
+ * @param replacementValues a map mapping the placeholder names (without
leading colons)
+ * to values to use as placeholders in the query.
+ * Can be null or empty if no placeholders need to be filled.
+ *
+ * @return The number of rows affected.
+ *
+ * @throws TorqueException if executing the statement fails.
+ */
+ public static int executeStatement(
+ final String statementString,
+ final Connection con,
+ final Map<String, JdbcTypedValue> replacementValues)
+ throws TorqueException
+ {
+ return ${peerImplGetter}().executeStatement(
+ statementString,
+ con,
+ replacementValues);
+ }
+
+
\ No newline at end of file
Modified:
db/torque/torque4/trunk/torque-templates/src/main/resources/org/apache/torque/templates/om/templates/peer/base/imports.vm
URL:
http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-templates/src/main/resources/org/apache/torque/templates/om/templates/peer/base/imports.vm?rev=1701342&r1=1701341&r2=1701342&view=diff
==============================================================================
---
db/torque/torque4/trunk/torque-templates/src/main/resources/org/apache/torque/templates/om/templates/peer/base/imports.vm
(original)
+++
db/torque/torque4/trunk/torque-templates/src/main/resources/org/apache/torque/templates/om/templates/peer/base/imports.vm
Sat Sep 5 02:18:04 2015
@@ -37,6 +37,7 @@ import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
+import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
Added:
db/torque/torque4/trunk/torque-test/src/test/java/org/apache/torque/generated/peer/ExecuteStatementsTest.java
URL:
http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-test/src/test/java/org/apache/torque/generated/peer/ExecuteStatementsTest.java?rev=1701342&view=auto
==============================================================================
---
db/torque/torque4/trunk/torque-test/src/test/java/org/apache/torque/generated/peer/ExecuteStatementsTest.java
(added)
+++
db/torque/torque4/trunk/torque-test/src/test/java/org/apache/torque/generated/peer/ExecuteStatementsTest.java
Sat Sep 5 02:18:04 2015
@@ -0,0 +1,68 @@
+package org.apache.torque.generated.peer;
+
+/*
+ * 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.
+ */
+
+import java.sql.Types;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.torque.BaseDatabaseTestCase;
+import org.apache.torque.test.dbobject.Author;
+import org.apache.torque.test.peer.AuthorPeer;
+import org.apache.torque.util.JdbcTypedValue;
+
+/**
+ * Tests executeStatement calls.
+ *
+ * @version $Id: $
+ */
+public class ExecuteStatementsTest extends BaseDatabaseTestCase
+{
+ private List<Author> authorList;
+
+ @Override
+ public void setUp() throws Exception
+ {
+ super.setUp();
+ cleanBookstore();
+ authorList = insertBookstoreData();
+ }
+
+ /**
+ * Test execution of a statement with string replacements
+ *
+ * @throws Exception if the test fails
+ */
+ public void testExecuteStatementWithStringReplacements() throws Exception
+ {
+ Map<String, JdbcTypedValue> replacements = new HashMap<String,
JdbcTypedValue>();
+ replacements.put("name", new JdbcTypedValue("Author 1",
Types.VARCHAR));
+ replacements.put("newname", new JdbcTypedValue("Author 1 changed",
Types.VARCHAR));
+
+ int updateCount = AuthorPeer.executeStatement(
+ "update " + AuthorPeer.TABLE_NAME + " set " + AuthorPeer.NAME
+ "=:newname where " + AuthorPeer.NAME + "=:name",
+ replacements);
+
+ assertEquals(1,updateCount);
+ authorList.get(0).setName("Author 1 changed");
+ verifyBookstore(authorList);
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]