blob: 25330e6e5b694947546ce5ec78063464c21c6230 [file] [log] [blame]
/*
* Copyright 2005 The Apache Software Foundation.
*
* Licensed 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;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.jdo.PersistenceManager;
import javax.jdo.Extent;
import javax.jdo.JDOFatalInternalException;
import javax.jdo.Query;
import javax.jdo.Transaction;
import org.apache.jdo.tck.JDO_Test;
import org.apache.jdo.tck.pc.company.Company;
import org.apache.jdo.tck.pc.company.CompanyModelReader;
import org.apache.jdo.tck.pc.company.Department;
import org.apache.jdo.tck.pc.company.Insurance;
import org.apache.jdo.tck.pc.company.Person;
import org.apache.jdo.tck.pc.company.Project;
import org.apache.jdo.tck.pc.mylib.PCPoint;
import org.apache.jdo.tck.pc.mylib.PrimitiveTypes;
public abstract class QueryTest extends JDO_Test {
/** */
public static final String SERIALZED_QUERY = "query.ser";
/**
* List of inserted instances (see methods insertPCPoints and
* getFromInserted).
*/
protected List inserted = new ArrayList();
// Helper methods to create persistent PCPoint instances
/** */
public void initDatabase(PersistenceManager pm, Class cls){
cleanupDatabase(pm, cls);
if (cls == PCPoint.class)
insertPCPoints(pm, 5);
else
throw new JDOFatalInternalException(
"Unsupported pc class for initDatabase " + cls);
}
/** */
protected void insertPCPoints(PersistenceManager pm, int numInsert) {
Transaction tx = pm.currentTransaction();
try {
tx.begin();
for(int i = 0; i<numInsert; i++) {
Object pc = new PCPoint(i, i);
pm.makePersistent(pc);
inserted.add(pc);
}
tx.commit();
tx = null;
if (debug) logger.debug("Total objects inserted : " + numInsert);
}
finally {
if ((tx != null) && tx.isActive())
tx.rollback();
}
}
/** */
public List getFromInserted(List list) {
if (list == null)
return null;
List result = new ArrayList();
for (Iterator iter = list.iterator(); iter.hasNext();) {
Object pc = iter.next();
for (Iterator iteri = inserted.iterator(); iteri.hasNext();) {
Object pci = iteri.next();
if (((PCPoint)pc).getX() == ((PCPoint)pci).getX()) {
result.add(pci);
break;
}
}
}
return result;
}
// Company model helper methods
/**
* Reads a graph of company model objects from the specified xml file. This
* methods explictly calls makePersistent for all named instances using the
* specified PersistenceManager. The method returns the CompanyModelReader
* instance allowing to access a compay model instance by name.
*/
public CompanyModelReader loadCompanyModel(PersistenceManager pm,
String filename) {
CompanyModelReader reader = new CompanyModelReader(filename);
Transaction tx = pm.currentTransaction();
tx.begin();
String[] names = reader.getBeanDefinitionNames();
for (int i = 0; i < names.length; i++) {
Object bean = reader.getBean(names[i]);
pm.makePersistent(bean);
if (debug) logger.debug("inserted " + bean);
}
tx.commit();
tx = null;
return reader;
}
/**
* Reads a graph of company model objects from the specified xml file. This
* methods calls makePersistent for all instances of the specified
* pcRootClass which then runs the reachability algorithm.
* The method returns the CompanyModelReader instance allowing to access
* a compay model instance by name.
*/
public CompanyModelReader loadCompanyModel(PersistenceManager pm,
String filename,
Class pcRootClass) {
CompanyModelReader reader = new CompanyModelReader(filename);
Transaction tx = pm.currentTransaction();
tx.begin();
Map rootBeans = reader.getBeansOfType(pcRootClass);
for (Iterator i = rootBeans.values().iterator(); i.hasNext();) {
Object bean = i.next();
pm.makePersistent(bean);
if (debug) logger.debug("inserted " + bean);
}
tx.commit();
tx = null;
return reader;
}
/** */
public void cleanupCompanyModel(PersistenceManager pm) {
Transaction tx = pm.currentTransaction();
if (tx.isActive()) tx.rollback();
try {
tx.begin();
cleanupDatabaseInternal(pm, Company.class);
cleanupDatabaseInternal(pm, Department.class);
cleanupDatabaseInternal(pm, Person.class);
cleanupDatabaseInternal(pm, Insurance.class);
cleanupDatabaseInternal(pm, Project.class);
tx.commit();
tx = null;
}
finally {
if ((tx != null) && tx.isActive())
tx.rollback();
}
}
// PrimitiveTypes helper methods (creation and query)
/** */
public void loadPrimitiveTypes(PersistenceManager pm) {
cleanupDatabase(pm, PrimitiveTypes.class);
insertPrimitiveTypes(pm);
}
/** */
protected void insertPrimitiveTypes(PersistenceManager pm) {
boolean bFlag = false;
String strValue = "";
char charValue = '\u0000';
int numInsert = 10;
Transaction tx = pm.currentTransaction();
try {
tx.begin();
for (int i = 1; i <= numInsert; i++ ) {
if (i%2 == 1) {
bFlag = true;
strValue = "Odd" + i;
charValue = 'O';
}
else {
bFlag = false;
strValue = "Even" + i;
charValue = 'E';
}
PrimitiveTypes primitiveObject = new PrimitiveTypes(
(long)i, bFlag, new Boolean(bFlag), (byte)i, new Byte((byte)i),
(short)i, new Short((short)i), (int) i, new Integer(i),
(long)i, new Long(i), (float)i, new Float(i),
(double)i, new Double(i), charValue, new Character(charValue),
Calendar.getInstance().getTime(), strValue,
new BigDecimal(String.valueOf(i)),
new BigInteger(String.valueOf(i)),
new Long(i));
pm.makePersistent(primitiveObject);
}
tx.commit();
tx = null;
if (debug) logger.debug("Total objects inserted : " + numInsert);
}
finally {
if ((tx != null) && tx.isActive())
tx.rollback();
}
}
/**
* Creates and executes a PrimitiveTypes query with the specified filter.
* The method checks whether the query returns the expected result.
*/
protected void runSimplePrimitiveTypesQuery(String filter,
PersistenceManager pm,
Collection expected,
String assertion) {
Query q = pm.newQuery();
q.setClass(PrimitiveTypes.class);
q.setFilter(filter);
Collection results = (Collection)q.execute();
if (debug)
logger.debug("execute '" + filter + "' returns " + results.size() +
" instance(s)");
checkQueryResultWithoutOrder(assertion, results, expected);
}
/**
* Creates and executes a PrimitiveTypes query with the specified filter,
* parameter declarations and parameter values. The method checks whether
* the query returns the expected result.
*/
protected void runParameterPrimitiveTypesQuery(String filter,
String paramDecl,
Object paramValue,
PersistenceManager pm,
Collection expected,
String assertion) {
Query q = pm.newQuery();
q.setClass(PrimitiveTypes.class);
q.setFilter(filter);
q.declareParameters(paramDecl);
Collection results = (Collection)q.execute(paramValue);
if (debug)
logger.debug("execute '" + filter + "' with param '" + paramValue +
"' returns " + results.size() + " instance(s)");
checkQueryResultWithoutOrder(assertion, results, expected);
}
// Helper methods to cleanup the datastore
/** */
public void cleanupDatabase(PersistenceManager pm, Class cls) {
Transaction tx = pm.currentTransaction();
if (tx.isActive()) tx.rollback();
try {
tx.begin();
cleanupDatabaseInternal(pm, cls);
tx.commit();
tx = null;
}
finally {
if ((tx != null) && tx.isActive())
tx.rollback();
}
}
/** */
protected void cleanupDatabaseInternal(PersistenceManager pm, Class cls) {
Extent e = pm.getExtent(cls, true);
for (Iterator i = e.iterator(); i.hasNext();) {
Object pc = i.next();
if (debug)
logger.debug("Deleted the existing " + cls.getName() +
" object " + pc);
pm.deletePersistent(pc);
}
}
// Helper methods to checka query result
/** */
protected void checkQueryResultWithOrder(String assertion,
Object result,
Collection expected) {
if (result == null) {
fail(assertion, "Query returns null");
}
if (!(result instanceof Collection)) {
fail(assertion,
"Query result is not a collection: " +
result.getClass().getName());
}
if (!compareOrderedResults((Collection)result, expected)) {
String lf = System.getProperty("line.separator");
fail(assertion,
"Wrong query result: " + lf +
"query returns: " + result + lf +
"expected result: " + expected);
}
}
/** This method implements the semantics of AbstractList.equals but
* does not require that the parameters actually be Lists.
*/
protected boolean compareOrderedResults(Collection first, Collection second) {
if (first == second) {
return true;
} else {
Iterator firstIterator = first.iterator();
Iterator secondIterator = second.iterator();
while (firstIterator.hasNext()) {
if (!secondIterator.hasNext()) {
// semantics of first.size() != second.size() without using size()
return false;
}
Object firstObject = firstIterator.next();
Object secondObject = secondIterator.next();
if (firstObject == null) {
if (secondObject != null) {
return false;
}
} else if (!firstObject.equals(secondObject)) {
return false;
}
}
if (secondIterator.hasNext()) {
// semantics of first.size() != second.size() without using size()
return false;
} else {
return true;
}
}
}
/** */
protected void checkQueryResultWithoutOrder(String assertion,
Object result,
Collection expected) {
if (result == null) {
fail(assertion, "Query returns null");
}
if (!(result instanceof Collection)) {
fail(assertion, "Query result is not a collection: " +
result.getClass().getName());
}
if (((Collection)result).size() != expected.size() ||
!((Collection)result).containsAll(expected)) {
fail(assertion, "Wrong query result" +
"\nexpected: " + new ArrayList(expected) +
"\ngot: " + new ArrayList((Collection)result));
}
}
// Debugging helper methods
/** */
protected void printOutput(Object results, Collection expected) {
if (!debug)
return;
Iterator iter = null;
PCPoint pcp = null;
if (results == null) {
logger.debug("Query returns null");
}
if (!(results instanceof Collection)) {
logger.debug("Query result is not a collection: " +
results.getClass().getName());
}
logger.debug("Retrived Objects are:");
iter = ((Collection)results).iterator();
while (iter.hasNext()) {
pcp = (PCPoint)iter.next();
logger.debug("X = " + pcp.getX() + "\tY = " + pcp.getY());
}
logger.debug("Expected Objects are:");
iter = ((Collection)expected).iterator();
while (iter.hasNext()) {
pcp = (PCPoint)iter.next();
logger.debug("X = " + pcp.getX() + "\tY = " + pcp.getY());
}
}
}