Index: src/conf/query.conf =================================================================== --- src/conf/query.conf (revision 497503) +++ src/conf/query.conf (working copy) @@ -84,4 +84,5 @@ org.apache.jdo.tck.query.sql.ShapeOfResult \ org.apache.jdo.tck.query.sql.NoCandidateClass \ org.apache.jdo.tck.query.sql.AllowedAPIMethods \ -org.apache.jdo.tck.query.sql.NewQuery +org.apache.jdo.tck.query.sql.NewQuery \ +org.apache.jdo.tck.query.sql.ExecuteWithMap Index: src/java/org/apache/jdo/tck/query/QueryTest.java =================================================================== --- src/java/org/apache/jdo/tck/query/QueryTest.java (revision 497503) +++ src/java/org/apache/jdo/tck/query/QueryTest.java (working copy) @@ -1194,6 +1194,49 @@ } /** + * Executes the given SQL string as a JDO SQL query with a Map. + * The result of that query is compared against the given argument + * expectedResult. + * If the expected result does not match the returned query result + * and the query is expected to pass, + * then the test case fails prompting argument assertion. + * Argument unique indicates, if the query is supposed + * to return a single result. + * Argument sql may contain the substring "{0}". + * All occurences of this substring are replaced + * by the value of PMF property "javax.jdo.mapping.Schema". + * @param assertion the assertion to prompt if the test case fails. + * @param sql the SQL string. + * @param candidateClass the candidate class. + * @param resultClass the result class. + * @param positive true if the query is expected to succeed + * @param parameters the parameters of the query in a Map. + * @param expectedResult the expected query result. + * @param unique indicates, if the query is supposed + * to return a single result. + */ + protected void executeSQLQueryWithMap(String assertion, String sql, + Class candidateClass, Class resultClass, boolean positive, + Object parameters, Object expectedResult, boolean unique) { + String schema = getPMFProperty("javax.jdo.mapping.Schema"); + sql = MessageFormat.format(sql, new Object[]{schema}); + if (logger.isDebugEnabled()) + logger.debug("Executing SQL query: " + sql); + Query query = getPM().newQuery("javax.jdo.query.SQL", sql); + if (unique) { + query.setUnique(unique); + } + if (candidateClass != null) { + query.setClass(candidateClass); + } + if (resultClass != null) { + query.setResultClass(resultClass); + } + execute(assertion, query, sql, false, + parameters, expectedResult, positive); + } + + /** * Executes the given query instance. * If argument parameters is an object array, * then it is passed as an argument Index: src/java/org/apache/jdo/tck/query/sql/ExecuteWithMap.java =================================================================== --- src/java/org/apache/jdo/tck/query/sql/ExecuteWithMap.java (revision 0) +++ src/java/org/apache/jdo/tck/query/sql/ExecuteWithMap.java (revision 0) @@ -0,0 +1,150 @@ +/* + * 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. + */ + +package org.apache.jdo.tck.query.sql; + +import java.util.HashMap; + +import org.apache.jdo.tck.pc.company.CompanyModelReader; +import org.apache.jdo.tck.pc.company.Person; +import org.apache.jdo.tck.pc.mylib.MylibReader; +import org.apache.jdo.tck.pc.mylib.PrimitiveTypes; +import org.apache.jdo.tck.query.QueryTest; +import org.apache.jdo.tck.util.BatchTestRunner; + +/** + *Title: ExecuteWithMap + *
+ *Keywords: query + *
+ *Assertion ID: A14.7-5. + *
+ *Assertion Description: + * If the parameter list is a Map, then the keys of the Map + * must be instances of Integer whose intValue is 1..n. + * The value in the Map corresponding to the key whose intValue is 1 + * is bound to the first ? in the SQL statement, and so forth. + */ +public class ExecuteWithMap extends QueryTest { + + /** */ + private static final String ASSERTION_FAILED = + "Assertion A14.7-5 (ExecuteWithMap)"; + + /** + * The main is called when the class + * is directly executed from the command line. + * @param args The arguments passed to the program. + */ + public static void main(String[] args) { + BatchTestRunner.run(ExecuteWithMap.class); + } + + /** The array of valid SQL queries. */ + private static final String[] VALID_SQL_QUERIES = { + "SELECT * FROM {0}.PrimitiveTypes WHERE intNotNull = ? " + + "OR stringNull = ?", + "SELECT * FROM {0}.persons WHERE FIRSTNAME = ? AND LASTNAME = ?" + + " AND MIDDLENAME = ? AND CITY = ?" + }; + + /** + * The expected results of valid SQL queries. + */ + private Object[] expectedResult = { + getTransientMylibInstancesAsList(new String[]{ + "primitiveTypesPositive", + "primitiveTypesCharacterStringLiterals"}), + getTransientCompanyModelInstancesAsList(new String[]{"emp2"}) + }; + + /** + * The Map of parameter values for valid SQL queries. + */ + private static HashMap hm1 = new HashMap(); + private static HashMap hm2 = new HashMap(); + private static HashMap illegalMapMissingKeyTwo = new HashMap(); + private static HashMap illegalMapContainsZeroKey = new HashMap(); + private static HashMap illegaMapContainsStringKey = new HashMap(); + static { + hm1.put((Object)new Integer(1), (Object)new Integer(4)); + hm1.put((Object)new Integer(2), (Object)"Even"); + hm2.put((Object)new Integer(1), (Object)"emp2First"); + hm2.put((Object)new Integer(2), (Object)"emp2Last"); + hm2.put((Object)new Integer(3), (Object)"emp2Middle"); + hm2.put((Object)new Integer(4), (Object)"New York"); + illegalMapMissingKeyTwo = (HashMap) hm2.clone(); + illegalMapMissingKeyTwo.remove((Object)new Integer(2)); + illegalMapContainsZeroKey = (HashMap) hm2.clone(); + illegalMapContainsZeroKey.remove((Object)new Integer(4)); + illegalMapContainsZeroKey.put((Object)new Integer(0), + (Object)"nozerothparam"); + illegaMapContainsStringKey = (HashMap) hm2.clone(); + illegaMapContainsStringKey.remove((Object)new Integer(4)); + illegaMapContainsStringKey.put((Object)new String("dog"), + (Object)"illegalStringParam"); + }; + private static HashMap[] parameterMap = new HashMap[]{hm1, hm2}; + + /** */ + public void testSetClass() { + boolean unique = false; + boolean positive = true; + if (isSQLSupported()) { + int index = 0; + executeSQLQueryWithMap(ASSERTION_FAILED, VALID_SQL_QUERIES[index], + PrimitiveTypes.class, null, positive, + parameterMap[index], expectedResult[index], unique); + + index = 1; + executeSQLQueryWithMap(ASSERTION_FAILED, VALID_SQL_QUERIES[index], + Person.class, null, positive, + parameterMap[index], expectedResult[index], unique); + } + } + + /** */ + public void testNegative() { + if (isSQLSupported()) { + String query = "SELECT * FROM {0}.persons WHERE FIRSTNAME = ? " + + "AND LASTNAME = ? AND MIDDLENAME = ? AND CITY = ? " + + "AND FUNDINGDEPT = ?"; + String singleStringQuery = query; + boolean unique = false; + boolean positive = false; + executeSQLQueryWithMap(ASSERTION_FAILED, query, Person.class, + null, positive, (Object)illegalMapMissingKeyTwo, + (Object)null, unique); + executeSQLQueryWithMap(ASSERTION_FAILED, query, Person.class, + null, positive, (Object)illegalMapContainsZeroKey, + (Object)null, unique); + executeSQLQueryWithMap(ASSERTION_FAILED, query, Person.class, + null, positive, (Object)illegaMapContainsStringKey, + (Object)null, unique); + } + } + + /** + * @see JDO_Test#localSetUp() + */ + protected void localSetUp() { + addTearDownClass(CompanyModelReader.getTearDownClasses()); + addTearDownClass(MylibReader.getTearDownClasses()); + loadAndPersistCompanyModel(getPM()); + loadAndPersistMylib(getPM()); + } +}