Author: brazil
Date: Thu Dec 1 09:30:34 2005
New Revision: 350282
URL: http://svn.apache.org/viewcvs?rev=350282&view=rev
Log:
JDO-166: Implement new JDO 2 query tests cases concerning deletion by query.
Added:
incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/query/delete/
incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/query/delete/DeleteCallback.java
incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/query/delete/DeletePersistentAll.java
incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/query/delete/DeleteQueryElements.java
Modified:
incubator/jdo/trunk/tck20/test/conf/alltests.conf
incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/query/QueryElementHolder.java
incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/query/QueryTest.java
Modified: incubator/jdo/trunk/tck20/test/conf/alltests.conf
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/tck20/test/conf/alltests.conf?rev=350282&r1=350281&r2=350282&view=diff
==============================================================================
--- incubator/jdo/trunk/tck20/test/conf/alltests.conf (original)
+++ incubator/jdo/trunk/tck20/test/conf/alltests.conf Thu Dec 1 09:30:34 2005
@@ -296,6 +296,9 @@
org.apache.jdo.tck.query.api.SetterReplacePreviousValues \
org.apache.jdo.tck.query.api.SingleStringQuery \
org.apache.jdo.tck.query.api.UnmodifiableQuery \
+org.apache.jdo.tck.query.delete.DeleteCallback \
+org.apache.jdo.tck.query.delete.DeletePersistentAll \
+org.apache.jdo.tck.query.delete.DeleteQueryElements \
org.apache.jdo.tck.query.jdoql.AssignmentPrePostIncrementDecrementNotSupported \
org.apache.jdo.tck.query.jdoql.Cast \
org.apache.jdo.tck.query.jdoql.CharacterAndStringLiterals \
Modified: incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/query/QueryElementHolder.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/query/QueryElementHolder.java?rev=350282&r1=350281&r2=350282&view=diff
==============================================================================
--- incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/query/QueryElementHolder.java (original)
+++ incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/query/QueryElementHolder.java Thu
Dec 1 09:30:34 2005
@@ -230,7 +230,7 @@
* Returns the unique JDOQL query element.
* @return the unique JDOQL query element.
*/
- protected boolean isUnique() {
+ public boolean isUnique() {
return this.unique != null && this.unique.booleanValue();
}
@@ -238,8 +238,16 @@
* Returns the unique JDOQL query element.
* @return the unique JDOQL query element.
*/
- protected boolean hasOrdering() {
+ public boolean hasOrdering() {
return this.ordering != null;
+ }
+
+ /**
+ * Returns the candtidate class JDOQL query element.
+ * @return the candtidate class JDOQL query element.
+ */
+ public Class getCandidateClass() {
+ return this.candidateClass;
}
/**
Modified: incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/query/QueryTest.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/query/QueryTest.java?rev=350282&r1=350281&r2=350282&view=diff
==============================================================================
--- incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/query/QueryTest.java (original)
+++ incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/query/QueryTest.java Thu Dec 1
09:30:34 2005
@@ -442,7 +442,7 @@
* @param o2 the second object
* @return <code>true</code> if <code>o1</code> and <code>o2</code>
equal.
*/
- private boolean equals(Object o1, Object o2) {
+ protected boolean equals(Object o1, Object o2) {
boolean result;
if (o1 == o2) {
result = true;
@@ -488,7 +488,7 @@
* @param o2 the second object array
* @return <code>true</code> if <code>o1</code> and <code>o2</code>
equal.
*/
- private boolean equalsObjectArray(Object[] o1, Object[] o2) {
+ protected boolean equalsObjectArray(Object[] o1, Object[] o2) {
boolean result = true;
if (o1 != o2) {
if (o1.length != o2.length) {
@@ -520,7 +520,7 @@
* @param o2 the second list
* @return <code>true</code> if <code>o1</code> and <code>o2</code>
equal.
*/
- private boolean equalsList(List o1, List o2) {
+ protected boolean equalsList(List o1, List o2) {
boolean result = true;
if (o1 != o2) {
if (o1.size() != o2.size()) {
@@ -553,7 +553,7 @@
* @param o2 the second collection
* @return <code>true</code> if <code>o1</code> and <code>o2</code>
equal.
*/
- private boolean equalsCollection(Collection o1, Collection o2) {
+ protected boolean equalsCollection(Collection o1, Collection o2) {
boolean result = true;
if (o1 != o2) {
if (o1.size() != o2.size()) {
@@ -583,7 +583,7 @@
* @param o2 the second map
* @return <code>true</code> if <code>o1</code> and <code>o2</code>
equal.
*/
- private boolean equalsMap(Map o1, Map o2) {
+ protected boolean equalsMap(Map o1, Map o2) {
boolean result = true;
if (o1 != o2) {
if (o1.size() != o2.size()) {
@@ -837,13 +837,13 @@
try {
query.compile();
if (!positive) {
- fail(assertion +
+ fail(assertion,
"Query compilation must throw JDOUserException: " +
queryText);
}
} catch (JDOUserException e) {
if (positive) {
- fail(assertion + "Query '" + queryText +
+ fail(assertion, "Query '" + queryText +
"' must be compilable. The exception message is: " +
e.getMessage());
}
@@ -947,7 +947,7 @@
*/
private Object execute(String assertion,
QueryElementHolder queryElementHolder, boolean asSingleString,
- Object[] parameters, Object expectedResult) {
+ Object parameters, Object expectedResult) {
Query query = asSingleString ?
queryElementHolder.getSingleStringQuery(pm) :
queryElementHolder.getAPIQuery(pm);
@@ -1058,15 +1058,24 @@
*/
private Object execute(String assertion, Query query,
String singleStringQuery, boolean hasOrdering,
- Object[] parameters, Object expectedResult, boolean positive) {
+ Object parameters, Object expectedResult, boolean positive) {
Object result = null;
PersistenceManager pm = getPM();
Transaction tx = pm.currentTransaction();
tx.begin();
try {
try {
- result = parameters != null ?
- query.executeWithArray(parameters) : query.execute();
+ if (parameters == null) {
+ result = query.execute();
+ } else if (parameters instanceof Object[]) {
+ result = query.executeWithArray((Object[])parameters);
+ } else if (parameters instanceof Map) {
+ result = query.executeWithMap((Map)parameters);
+ } else {
+ throw new IllegalArgumentException("Argument parameters " +
+ "must be instance of Object[], Map, or null.");
+ }
+
if (logger.isDebugEnabled()) {
logger.debug("Query result: " + ConversionHelper.
convertObjectArrayElements(result));
@@ -1081,7 +1090,7 @@
expectedResult);
}
} else {
- fail(assertion + "Query must throw JDOUserException: " +
+ fail(assertion, "Query must throw JDOUserException: " +
singleStringQuery);
}
} finally {
@@ -1097,5 +1106,154 @@
}
}
return result;
+ }
+
+ /**
+ * Converts the given query element holder instance to a
+ * JDO query instance.
+ * Calls {@link Query#deletePersistentAll()}, or
+ * {@link Query#deletePersistentAll(java.util.Map), or
+ * {@link Query#deletePersistentAll(java.lang.Object[])
+ * depending on the type of argument <code>parameters</code>.
+ * If the number of deleted objects does not
+ * match <code>expectedNrOfDeletedObjects</code>,
+ * then the test case fails prompting argument <code>assertion</code>.
+ * @param assertion the assertion to prompt if the test case fails.
+ * @param queryElementHolder the query to execute.
+ * @param parameters the parmaters of the query.
+ * @param expectedNrOfDeletedObjects the expected number of deleted objects.
+ */
+ protected void deletePersistentAllByAPIQuery(String assertion,
+ QueryElementHolder queryElementHolder,
+ Object parameters, long expectedNrOfDeletedObjects) {
+ if (logger.isDebugEnabled()) {
+ logger.debug("Deleting persistent by API query: " +
+ queryElementHolder);
+ }
+ delete(assertion, queryElementHolder, false,
+ parameters, expectedNrOfDeletedObjects);
+ }
+
+ /**
+ * Converts the given query element holder instance to a
+ * JDO query instance.
+ * Calls {@link Query#deletePersistentAll()}, or
+ * {@link Query#deletePersistentAll(java.util.Map), or
+ * {@link Query#deletePersistentAll(java.lang.Object[])
+ * depending on the type of argument <code>parameters</code>.
+ * If the number of deleted objects does not
+ * match <code>expectedNrOfDeletedObjects</code>,
+ * then the test case fails prompting argument <code>assertion</code>.
+ * @param assertion the assertion to prompt if the test case fails.
+ * @param queryElementHolder the query to execute.
+ * @param parameters the parmaters of the query.
+ * @param expectedNrOfDeletedObjects the expected number of deleted objects.
+ */
+ protected void deletePersistentAllBySingleStringQuery(String assertion,
+ QueryElementHolder queryElementHolder,
+ Object parameters, long expectedNrOfDeletedObjects) {
+ if (logger.isDebugEnabled()) {
+ logger.debug("Deleting persistent by single string query: " +
+ queryElementHolder);
+ }
+ delete(assertion, queryElementHolder, true,
+ parameters, expectedNrOfDeletedObjects);
+ }
+
+ /**
+ * Converts the given query element holder instance to a
+ * JDO query based on argument <code>asSingleString</code>.
+ * Calls {@link Query#deletePersistentAll()}, or
+ * {@link Query#deletePersistentAll(java.util.Map), or
+ * {@link Query#deletePersistentAll(java.lang.Object[])
+ * depending on the type of argument <code>parameters</code>.
+ * If the number of deleted objects does not
+ * match <code>expectedNrOfDeletedObjects</code>,
+ * then the test case fails prompting argument <code>assertion</code>.
+ * @param assertion the assertion to prompt if the test case fails.
+ * @param queryElementHolder the query to execute.
+ * @param asSingleString determines if the query is executed as
+ * single string query or as API query.
+ * @param parameters the parmaters of the query.
+ * @param expectedNrOfDeletedObjects the expected number of deleted objects.
+ */
+ private void delete(String assertion,
+ QueryElementHolder queryElementHolder, boolean asSingleString,
+ Object parameters, long expectedNrOfDeletedObjects) {
+ Query query = asSingleString ?
+ queryElementHolder.getSingleStringQuery(pm) :
+ queryElementHolder.getAPIQuery(pm);
+ delete(assertion, query, queryElementHolder.toString(),
+ parameters, expectedNrOfDeletedObjects);
+ boolean positive = expectedNrOfDeletedObjects >= 0;
+ if (positive) {
+ execute(assertion, queryElementHolder, asSingleString, parameters,
+ queryElementHolder.isUnique() ? null : new ArrayList());
+ }
+ }
+
+ /**
+ * Calls {@link Query#deletePersistentAll()}, or
+ * {@link Query#deletePersistentAll(java.util.Map), or
+ * {@link Query#deletePersistentAll(java.lang.Object[])
+ * depending on the type of argument <code>parameters</code>.
+ * If the number of deleted objects does not
+ * match <code>expectedNrOfDeletedObjects</code>,
+ * then the test case fails prompting argument <code>assertion</code>.
+ * Argument <code>singleStringQuery</code> is only used as part
+ * of the failure message.
+ * @param assertion the assertion to prompt if the test case fails.
+ * @param query the query to execute.
+ * @param singleStringQuery the single string representation of the query.
+ * @param parameters the parmaters of the query.
+ * @param expectedNrOfDeletedObjects the expected number of deleted objects.
+ */
+ private void delete(String assertion, Query query,
+ String singleStringQuery, Object parameters,
+ long expectedNrOfDeletedObjects) {
+ boolean positive = expectedNrOfDeletedObjects >= 0;
+ PersistenceManager pm = getPM();
+ Transaction tx = pm.currentTransaction();
+ tx.begin();
+ try {
+ try {
+ long nr;
+ if (parameters == null) {
+ nr = query.deletePersistentAll();
+ } else if (parameters instanceof Object[]) {
+ nr = query.deletePersistentAll((Object[])parameters);
+ } else if (parameters instanceof Map) {
+ nr = query.deletePersistentAll((Map)parameters);
+ } else {
+ throw new IllegalArgumentException("Argument parameters " +
+ "must be instance of Object[], Map, or null.");
+ }
+ if (logger.isDebugEnabled()) {
+ logger.debug(nr + " objects deleted.");
+ }
+
+ if (positive) {
+ if (nr != expectedNrOfDeletedObjects) {
+ fail(assertion, "deletePersistentAll returned " + nr +
+ ", expected is " + expectedNrOfDeletedObjects +
+ ". Query: " +singleStringQuery);
+ }
+ } else {
+ fail(assertion, "deletePersistentAll must throw JDOUserException: " +
+ singleStringQuery);
+ }
+ } finally {
+ query.closeAll();
+ }
+ tx.commit();
+ } catch (JDOUserException e) {
+ if (positive) {
+ throw e;
+ }
+ } finally {
+ if (tx.isActive()) {
+ tx.rollback();
+ }
+ }
}
}
Added: incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/query/delete/DeleteCallback.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/query/delete/DeleteCallback.java?rev=350282&view=auto
==============================================================================
--- incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/query/delete/DeleteCallback.java
(added)
+++ incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/query/delete/DeleteCallback.java
Thu Dec 1 09:30:34 2005
@@ -0,0 +1,395 @@
+/*
+ * 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.delete;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.jdo.JDOHelper;
+import javax.jdo.PersistenceManager;
+import javax.jdo.Query;
+import javax.jdo.Transaction;
+import javax.jdo.listener.DeleteLifecycleListener;
+import javax.jdo.listener.InstanceLifecycleEvent;
+import javax.jdo.listener.StoreLifecycleListener;
+
+import org.apache.jdo.tck.JDO_Test;
+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.QueryElementHolder;
+import org.apache.jdo.tck.query.QueryTest;
+import org.apache.jdo.tck.util.BatchTestRunner;
+import org.apache.jdo.tck.util.ConversionHelper;
+
+/**
+ *<B>Title:</B> Delete Persistent All.
+ *<BR>
+ *<B>Keywords:</B> query
+ *<BR>
+ *<B>Assertion ID:</B> A14.8-4
+ *<BR>
+ *<B>Assertion Description: </B>
+ * Dirty instances of affected classes are first flushed to the datastore.
+ * Instances already in the cache when deleted via these methods
+ * or brought into the cache as a result of these methods
+ * undergo the life cycle transitions as if deletePersistent
+ * had been called on them.
+ * That is, if an affected class implements the DeleteCallback interface,
+ * the instances to be deleted are instantiated in memory and
+ * the jdoPreDelete method is called prior
+ * to deleting the instance in the datastore.
+ * If any LifecycleListener instances are registered with affected classes,
+ * these listeners are called for each deleted instance.
+ * Before returning control to the application,
+ * instances of affected classes in the cache are refreshed
+ * by the implementation so their status in the cache reflects
+ * whether they were deleted from the datastore.
+ */
+public class DeleteCallback extends QueryTest {
+
+ /** */
+ private static final String ASSERTION_FAILED =
+ "Assertion A14.8-4 (DeleteCallback) failed: ";
+
+ /**
+ * The array of valid queries which may be executed as
+ * single string queries and as API queries.
+ */
+ private static final QueryElementHolder[] VALID_QUERIES = {
+ new QueryElementHolder(
+ /*UNIQUE*/ null,
+ /*RESULT*/ null,
+ /*INTO*/ null,
+ /*FROM*/ Person.class,
+ /*EXCLUDE*/ null,
+ /*WHERE*/ null,
+ /*VARIABLES*/ null,
+ /*PARAMETERS*/ null,
+ /*IMPORTS*/ null,
+ /*GROUP BY*/ null,
+ /*ORDER BY*/ null,
+ /*FROM*/ null,
+ /*TO*/ null),
+ new QueryElementHolder(
+ /*UNIQUE*/ null,
+ /*RESULT*/ null,
+ /*INTO*/ null,
+ /*FROM*/ PrimitiveTypes.class,
+ /*EXCLUDE*/ null,
+ /*WHERE*/ null,
+ /*VARIABLES*/ null,
+ /*PARAMETERS*/ null,
+ /*IMPORTS*/ null,
+ /*GROUP BY*/ null,
+ /*ORDER BY*/ null,
+ /*FROM*/ null,
+ /*TO*/ null)
+ };
+
+ /**
+ * The expected results of valid queries.
+ */
+ private List[] expectedResult = {
+ getCompanyModelInstancesAsList(new String[]{
+ "emp1", "emp2", "emp3", "emp4", "emp5"}),
+ getMylibInstancesAsList(new String[]{
+ "primitiveTypesPositive",
+ "primitiveTypesNegative",
+ "primitiveTypesCharacterStringLiterals"})
+ };
+
+ /**
+ * The <code>main</code> 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(DeleteCallback.class);
+ }
+
+ /** */
+ public void testRelationshipsAPI() {
+ queryUpdateDeleteVerify(0, "middlename", false);
+ }
+
+ /** */
+ public void testRelationshipsSingleString() {
+ queryUpdateDeleteVerify(0, "middlename", true);
+ }
+
+ /** */
+ public void testNoRelationshipsAPI() {
+ queryUpdateDeleteVerify(1, "stringNull", false);
+ }
+
+ /** */
+ public void testNoRelationshipsSingleString() {
+ queryUpdateDeleteVerify(1, "stringNull", true);
+ }
+
+ /**
+ * @see JDO_Test#localSetUp()
+ */
+ protected void localSetUp() {
+ loadCompanyModel(getPM(), COMPANY_TESTDATA);
+ addTearDownClass(CompanyModelReader.getTearDownClasses());
+ loadMylib(getPM(), MYLIB_TESTDATA);
+ addTearDownClass(MylibReader.getTearDownClasses());
+ }
+
+ /**
+ * Adds a lifecycle listener to the persistence manager.
+ * Converts the query element holder instance refered to by argument
+ * <code>index</code> to a JDO query instance based on argument
+ * <code>asSingleString</code>.
+ * Executes the query instance and marks all queried pc instances as dirty
+ * by calling {@link JDOHelper#makeDirty(java.lang.Object, java.lang.String)}.
+ * Passes argument <code>fieldName</code> to that call.
+ * Afterwards, calls {@link Query#deletePersistentAll()}, and
+ * verifies the lifecycle callbacks and the lifecycle states.
+ * @param index the index of the query element hoplder instance
+ * @param fieldName the field name passed as argument to
+ * {@link JDOHelper#makeDirty(java.lang.Object, java.lang.String)
+ * @param asSingleString determines if the query is executed as
+ * single string query or as API query.
+ */
+ private void queryUpdateDeleteVerify(int index,
+ String fieldName, boolean asSingleString) {
+ PersistenceManager pm = getPM();
+ Transaction transaction = pm.currentTransaction();
+ transaction.begin();
+ try
+ {
+ LifecycleVerifyer lifecycleVerifyer;
+
+ // query, check result, update
+ Query query = asSingleString ?
+ VALID_QUERIES[index].getSingleStringQuery(pm) :
+ VALID_QUERIES[index].getAPIQuery(pm);
+ if (logger.isDebugEnabled()) {
+ if (asSingleString) {
+ logger.debug("Executing single string query: " +
+ VALID_QUERIES[index]);
+ } else {
+ logger.debug("Executing API query: " +
+ VALID_QUERIES[index]);
+ }
+ }
+ Collection result = (Collection) query.execute();
+ try {
+ if (logger.isDebugEnabled()) {
+ logger.debug("Query result: " + ConversionHelper.
+ convertObjectArrayElements(result));
+ }
+ checkQueryResultWithoutOrder(ASSERTION_FAILED, result, expectedResult[index]);
+
+ // add lifecycle listener
+ lifecycleVerifyer = new LifecycleVerifyer(result);
+ pm.addInstanceLifecycleListener(lifecycleVerifyer,
+ new Class[]{VALID_QUERIES[index].getCandidateClass()});
+
+ // update
+ for (Iterator i = result.iterator(); i.hasNext(); ) {
+ Object pc = i.next();
+ if (logger.isDebugEnabled()) {
+ logger.debug("Calling JDOHelper.makeDirty(" +
+ pc + ", \"" + fieldName + "\")");
+ }
+ JDOHelper.makeDirty(pc, fieldName);
+ }
+ } finally
+ {
+ query.close(result);
+ }
+
+ // delete
+ if (logger.isDebugEnabled()) {
+ if (asSingleString) {
+ logger.debug("Deleting persistent by single string query: " +
+ VALID_QUERIES[index]);
+ } else {
+ logger.debug("Deleting persistent by API query: " +
+ VALID_QUERIES[index]);
+ }
+ }
+ long nr = query.deletePersistentAll();
+ if (logger.isDebugEnabled()) {
+ logger.debug(nr + " objects deleted.");
+ }
+
+ // verify
+ if (logger.isDebugEnabled()) {
+ logger.debug("Verifying callbacks and states.");
+ }
+ lifecycleVerifyer.verifyCallbacksAndStates();
+ } finally {
+ if (transaction.isActive()) {
+ transaction.rollback();
+ }
+ }
+ }
+
+ /**
+ * A lifecycle listener which may be added to persistence managers.
+ * Gathers delete events and store events and keeps those
+ * in a list.
+ * Method {@link LifecycleVerifyer#verifyCallbacksAndStates()}
+ * may be called to check if the right events have been called
+ * on all expected instances.
+ * The expected instances are passed through
+ * {@link LifecycleVerifyer#LifecycleVerifyer(Collection).
+ */
+ private class LifecycleVerifyer
+ implements DeleteLifecycleListener, StoreLifecycleListener {
+
+ /** The oids of expected pc instances. */
+ private Collection expectedOids = new HashSet();
+
+ /** The list of events. */
+ private List events = new ArrayList();
+
+ /**
+ * Argument <code>expectedPCInstances</code> holds pc instances
+ * which are expected to be sources of events.
+ * @param expectedPCInstances the pc instances
+ * which are expected to be sources of events.
+ */
+ public LifecycleVerifyer(Collection expectedPCInstances) {
+ for (Iterator i = expectedPCInstances.iterator(); i.hasNext(); ) {
+ this.expectedOids.add(JDOHelper.getObjectId(i.next()));
+ }
+ }
+
+ /**
+ * Verifies if the right events have been called for all
+ * expected pc instances.
+ * All store events must have been fired before the
+ * first delete event has been fired.
+ * Furthermore, checks if pc instances kept in
+ * delete events have state persistent-deleted.
+ * The test case fails if one of these conditions
+ * is violated.
+ */
+ public void verifyCallbacksAndStates() {
+ // The two collections are filled iterating through the list of
+ // events. Finally, they are compared against field expectedOids.
+ // Note: Set implementations are used instead of list
+ // implementations two eliminate duplicates. Duplicates may occur
+ // if multiple updates or deletions are executed for the same
+ // pc instances.
+ Collection oidsOfDeletedInstances = new HashSet();
+ Collection oidsOfUpdateInstances = new HashSet();
+
+ boolean hasDeleteEventBeenPassed = false;
+ int size = events.size();
+ for (int i = 0; i < size; i++) {
+ InstanceLifecycleEvent event =
+ (InstanceLifecycleEvent) this.events.get(i);
+ Object source = event.getSource();
+ int eventType = event.getEventType();
+ if (eventType == InstanceLifecycleEvent.DELETE) {
+ if (logger.isDebugEnabled()) {
+ logger.debug("Verifying delete event on " +
+ JDOHelper.getObjectId(source));
+ }
+ hasDeleteEventBeenPassed = true;
+ if (!JDOHelper.isDeleted(source)) {
+ fail(ASSERTION_FAILED,
+ "PC instance must have persistent deleted " +
+ "state: " + source);
+ }
+ oidsOfDeletedInstances.add(JDOHelper.getObjectId(source));
+ } else if (eventType == InstanceLifecycleEvent.STORE) {
+ if (logger.isDebugEnabled()) {
+ logger.debug("Verifying store event on " +
+ JDOHelper.getObjectId(source));
+ }
+
+ if (hasDeleteEventBeenPassed) {
+ fail(ASSERTION_FAILED,
+ "PC instances must not be flushed " +
+ "after delete has been executed.");
+ }
+ oidsOfUpdateInstances.add(JDOHelper.getObjectId(source));
+ }
+ }
+
+ if (!equalsCollection(oidsOfDeletedInstances,
+ this.expectedOids)) {
+ String lf = System.getProperty("line.separator");
+ fail(ASSERTION_FAILED, "Got delete events for oids " +
+ oidsOfDeletedInstances + '.' + lf +
+ "Expected deleted events for oids " +
+ this.expectedOids + '.');
+ } else if (!equalsCollection(oidsOfUpdateInstances,
+ this.expectedOids)) {
+ String lf = System.getProperty("line.separator");
+ fail(ASSERTION_FAILED, "Got store events for oids " +
+ oidsOfUpdateInstances + '.' + lf +
+ "Expected store events for oids " +
+ this.expectedOids + '.');
+ }
+ }
+
+ /**
+ * @see DeleteLifecycleListener#preDelete(javax.jdo.listener.InstanceLifecycleEvent)
+ */
+ public void preDelete(InstanceLifecycleEvent event) {
+ if (logger.isDebugEnabled()) {
+ logger.debug("preDelete event: " +
+ JDOHelper.getObjectId(event.getSource()));
+ }
+ }
+
+ /**
+ * @see DeleteLifecycleListener#postDelete(javax.jdo.listener.InstanceLifecycleEvent)
+ */
+ public void postDelete(InstanceLifecycleEvent event) {
+ this.events.add(event);
+ if (logger.isDebugEnabled()) {
+ logger.debug("postDelete event: " +
+ JDOHelper.getObjectId(event.getSource()));
+ }
+ }
+
+ /**
+ * @see StoreLifecycleListener#preStore(javax.jdo.listener.InstanceLifecycleEvent)
+ */
+ public void preStore(InstanceLifecycleEvent event) {
+ if (logger.isDebugEnabled()) {
+ logger.debug("preStore event: " +
+ JDOHelper.getObjectId(event.getSource()));
+ }
+ }
+
+ /**
+ * @see StoreLifecycleListener#postStore(javax.jdo.listener.InstanceLifecycleEvent)
+ */
+ public void postStore(InstanceLifecycleEvent event) {
+ this.events.add(event);
+ if (logger.isDebugEnabled()) {
+ logger.debug("postStore event: " +
+ JDOHelper.getObjectId(event.getSource()));
+ }
+ }
+ }
+}
Added: incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/query/delete/DeletePersistentAll.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/query/delete/DeletePersistentAll.java?rev=350282&view=auto
==============================================================================
--- incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/query/delete/DeletePersistentAll.java
(added)
+++ incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/query/delete/DeletePersistentAll.java
Thu Dec 1 09:30:34 2005
@@ -0,0 +1,145 @@
+/*
+ * 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.delete;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.jdo.tck.JDO_Test;
+import org.apache.jdo.tck.pc.company.CompanyModelReader;
+import org.apache.jdo.tck.pc.company.Person;
+import org.apache.jdo.tck.query.QueryElementHolder;
+import org.apache.jdo.tck.query.QueryTest;
+import org.apache.jdo.tck.util.BatchTestRunner;
+
+/**
+ *<B>Title:</B> Delete Persistent All.
+ *<BR>
+ *<B>Keywords:</B> query
+ *<BR>
+ *<B>Assertion ID:</B> A14.8-1, A14.8-2
+ *<BR>
+ *<B>Assertion Description: </B>
+ * These methods delete the instances of affected classes
+ * that pass the filter, and all dependent instances.
+ * Affected classes are the candidate class and
+ * its persistence-capable subclasses.
+ *
+ * The number of instances of affected classes that were deleted is returned.
+ * Embedded instances and dependent instances are not counted
+ * in the return value.
+ */
+public class DeletePersistentAll extends QueryTest {
+
+ /** */
+ private static final String ASSERTION_FAILED =
+ "Assertion A14.8-1 (DeletePersistentAll) failed: ";
+
+ /**
+ * The array of valid queries which may be executed as
+ * single string queries and as API queries.
+ */
+ private static final QueryElementHolder[] VALID_QUERIES = {
+ new QueryElementHolder(
+ /*UNIQUE*/ null,
+ /*RESULT*/ null,
+ /*INTO*/ null,
+ /*FROM*/ Person.class,
+ /*EXCLUDE*/ null,
+ /*WHERE*/ null,
+ /*VARIABLES*/ null,
+ /*PARAMETERS*/ null,
+ /*IMPORTS*/ null,
+ /*GROUP BY*/ null,
+ /*ORDER BY*/ null,
+ /*FROM*/ null,
+ /*TO*/ null),
+ new QueryElementHolder(
+ /*UNIQUE*/ null,
+ /*RESULT*/ null,
+ /*INTO*/ null,
+ /*FROM*/ Person.class,
+ /*EXCLUDE*/ null,
+ /*WHERE*/ "firstname == param",
+ /*VARIABLES*/ null,
+ /*PARAMETERS*/ "String param",
+ /*IMPORTS*/ null,
+ /*GROUP BY*/ null,
+ /*ORDER BY*/ null,
+ /*FROM*/ null,
+ /*TO*/ null)
+ };
+
+ /**
+ * The <code>main</code> 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(DeletePersistentAll.class);
+ }
+
+ /** */
+ public void testNoParametersAPI() {
+ deletePersistentAllByAPIQuery(ASSERTION_FAILED,
+ VALID_QUERIES[0], null, 5);
+ }
+
+ /** */
+ public void testNoParametersSingleString() {
+ deletePersistentAllBySingleStringQuery(ASSERTION_FAILED,
+ VALID_QUERIES[0], null, 5);
+ }
+
+ /** */
+ public void testObjectArrayParametersAPI() {
+ Object[] parameters = new Object[] {"emp1First"};
+ deletePersistentAllByAPIQuery(ASSERTION_FAILED,
+ VALID_QUERIES[1], parameters, 1);
+ }
+
+ /** */
+ public void testObjectArrayParametersSingleString() {
+ Object[] parameters = new Object[] {"emp1First"};
+ deletePersistentAllBySingleStringQuery(ASSERTION_FAILED,
+ VALID_QUERIES[1], parameters, 1);
+ }
+
+ /** */
+ public void testMapParametersAPI() {
+ Map parameters = new HashMap();
+ parameters.put("param", "emp1First");
+ deletePersistentAllByAPIQuery(ASSERTION_FAILED,
+ VALID_QUERIES[1], parameters, 1);
+ }
+
+ /** */
+ public void testMapParametersSingleString() {
+ Map parameters = new HashMap();
+ parameters.put("param", "emp1First");
+ deletePersistentAllBySingleStringQuery(ASSERTION_FAILED,
+ VALID_QUERIES[1], parameters, 1);
+ }
+
+ /**
+ * @see JDO_Test#localSetUp()
+ */
+ protected void localSetUp() {
+ loadCompanyModel(getPM(), COMPANY_TESTDATA);
+ addTearDownClass(CompanyModelReader.getTearDownClasses());
+ }
+}
Added: incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/query/delete/DeleteQueryElements.java
URL: http://svn.apache.org/viewcvs/incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/query/delete/DeleteQueryElements.java?rev=350282&view=auto
==============================================================================
--- incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/query/delete/DeleteQueryElements.java
(added)
+++ incubator/jdo/trunk/tck20/test/java/org/apache/jdo/tck/query/delete/DeleteQueryElements.java
Thu Dec 1 09:30:34 2005
@@ -0,0 +1,250 @@
+/*
+ * 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.delete;
+
+import java.math.BigDecimal;
+
+import org.apache.jdo.tck.JDO_Test;
+import org.apache.jdo.tck.pc.company.CompanyModelReader;
+import org.apache.jdo.tck.pc.company.FullTimeEmployee;
+import org.apache.jdo.tck.pc.company.Person;
+import org.apache.jdo.tck.query.QueryElementHolder;
+import org.apache.jdo.tck.query.QueryTest;
+import org.apache.jdo.tck.query.result.classes.FullName;
+import org.apache.jdo.tck.util.BatchTestRunner;
+
+/**
+ *<B>Title:</B> Delete Query Elements.
+ *<BR>
+ *<B>Keywords:</B> query
+ *<BR>
+ *<B>Assertion ID:</B> A14.8-3
+ *<BR>
+ *<B>Assertion Description: </B>
+ * Query elements filter, parameters, imports, variables,
+ * and unique are valid in queries used for delete.
+ * Elements result, result class, range, grouping, and ordering are invalid.
+ * If any of these elements is set to its non-default value
+ * when one of the deletePersistentAll methods is called,
+ * a JDOUserException is thrown and no instances are deleted.
+ */
+public class DeleteQueryElements extends QueryTest {
+
+ /** */
+ private static final String ASSERTION_FAILED =
+ "Assertion A14.8-1 (DeleteQueryElements) failed: ";
+
+ /**
+ * The array of valid queries which may be executed as
+ * single string queries and as API queries.
+ */
+ private static final QueryElementHolder[] VALID_QUERIES = {
+ new QueryElementHolder(
+ /*UNIQUE*/ Boolean.TRUE,
+ /*RESULT*/ null,
+ /*INTO*/ null,
+ /*FROM*/ FullTimeEmployee.class,
+ /*EXCLUDE*/ null,
+ /*WHERE*/ "salary > 10000 & projects.contains(project) & " +
+ "project.budget > limit",
+ /*VARIABLES*/ "Project project",
+ /*PARAMETERS*/ "BigDecimal limit",
+ /*IMPORTS*/ "import org.apache.jdo.tck.pc.company.Project; " +
+ "import java.math.BigDecimal;",
+ /*GROUP BY*/ null,
+ /*ORDER BY*/ null,
+ /*FROM*/ null,
+ /*TO*/ null)
+ };
+
+ /**
+ * The array of invalid queries which may be executed as
+ * single string queries and as API queries.
+ */
+ private static final QueryElementHolder[] INVALID_QUERIES = {
+ // The query is invalid because it defines a result clause.
+ new QueryElementHolder(
+ /*UNIQUE*/ null,
+ /*RESULT*/ "firstname, lastname",
+ /*INTO*/ null,
+ /*FROM*/ Person.class,
+ /*EXCLUDE*/ null,
+ /*WHERE*/ null,
+ /*VARIABLES*/ null,
+ /*PARAMETERS*/ null,
+ /*IMPORTS*/ null,
+ /*GROUP BY*/ null,
+ /*ORDER BY*/ null,
+ /*FROM*/ null,
+ /*TO*/ null),
+ // The query is invalid because it defines a result class.
+ new QueryElementHolder(
+ /*UNIQUE*/ null,
+ /*RESULT*/ null,
+ /*INTO*/ FullName.class,
+ /*FROM*/ Person.class,
+ /*EXCLUDE*/ null,
+ /*WHERE*/ null,
+ /*VARIABLES*/ null,
+ /*PARAMETERS*/ null,
+ /*IMPORTS*/ null,
+ /*GROUP BY*/ null,
+ /*ORDER BY*/ null,
+ /*FROM*/ null,
+ /*TO*/ null),
+ // The query is invalid because it defines a result clause
+ // and a result class.
+ new QueryElementHolder(
+ /*UNIQUE*/ null,
+ /*RESULT*/ "firstname, lastname",
+ /*INTO*/ FullName.class,
+ /*FROM*/ Person.class,
+ /*EXCLUDE*/ null,
+ /*WHERE*/ null,
+ /*VARIABLES*/ null,
+ /*PARAMETERS*/ null,
+ /*IMPORTS*/ null,
+ /*GROUP BY*/ null,
+ /*ORDER BY*/ null,
+ /*FROM*/ null,
+ /*TO*/ null),
+ // The query is invalid because it defines a grouping clause.
+ new QueryElementHolder(
+ /*UNIQUE*/ null,
+ /*RESULT*/ null,
+ /*INTO*/ null,
+ /*FROM*/ Person.class,
+ /*EXCLUDE*/ null,
+ /*WHERE*/ null,
+ /*VARIABLES*/ null,
+ /*PARAMETERS*/ null,
+ /*IMPORTS*/ null,
+ /*GROUP BY*/ "lastname",
+ /*ORDER BY*/ null,
+ /*FROM*/ null,
+ /*TO*/ null),
+ // The query is invalid because it defines a result clause
+ // and a grouping clause
+ new QueryElementHolder(
+ /*UNIQUE*/ null,
+ /*RESULT*/ "lastname",
+ /*INTO*/ null,
+ /*FROM*/ Person.class,
+ /*EXCLUDE*/ null,
+ /*WHERE*/ null,
+ /*VARIABLES*/ null,
+ /*PARAMETERS*/ null,
+ /*IMPORTS*/ null,
+ /*GROUP BY*/ "lastname",
+ /*ORDER BY*/ null,
+ /*FROM*/ null,
+ /*TO*/ null),
+ // The query is invalid because it defines an ordering clause.
+ new QueryElementHolder(
+ /*UNIQUE*/ null,
+ /*RESULT*/ null,
+ /*INTO*/ null,
+ /*FROM*/ Person.class,
+ /*EXCLUDE*/ null,
+ /*WHERE*/ null,
+ /*VARIABLES*/ null,
+ /*PARAMETERS*/ null,
+ /*IMPORTS*/ null,
+ /*GROUP BY*/ null,
+ /*ORDER BY*/ "lastname",
+ /*FROM*/ null,
+ /*TO*/ null),
+ // The query is invalid because it defines a range clause.
+ new QueryElementHolder(
+ /*UNIQUE*/ null,
+ /*RESULT*/ null,
+ /*INTO*/ null,
+ /*FROM*/ Person.class,
+ /*EXCLUDE*/ null,
+ /*WHERE*/ null,
+ /*VARIABLES*/ null,
+ /*PARAMETERS*/ null,
+ /*IMPORTS*/ null,
+ /*GROUP BY*/ null,
+ /*ORDER BY*/ null,
+ /*FROM*/ "0",
+ /*TO*/ "5"),
+ // The query is valid but deletePersistentAll is expected
+ // to throw a JDOUserException because it defines a
+ // unique clause but it affects multiple rows in the database.
+ new QueryElementHolder(
+ /*UNIQUE*/ Boolean.TRUE,
+ /*RESULT*/ null,
+ /*INTO*/ null,
+ /*FROM*/ Person.class,
+ /*EXCLUDE*/ null,
+ /*WHERE*/ null,
+ /*VARIABLES*/ null,
+ /*PARAMETERS*/ null,
+ /*IMPORTS*/ null,
+ /*GROUP BY*/ null,
+ /*ORDER BY*/ null,
+ /*FROM*/ null,
+ /*TO*/ null)
+ };
+
+ /** Parameters of valid queries. */
+ private static Object[][] parameters = {
+ {new BigDecimal("2500000")}
+ };
+
+ /**
+ * The <code>main</code> 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(DeleteQueryElements.class);
+ }
+
+ /** */
+ public void testAPI() {
+ int index = 0;
+ deletePersistentAllByAPIQuery(ASSERTION_FAILED,
+ VALID_QUERIES[index], parameters[index], 1);
+ }
+
+ /** */
+ public void testSingleString() {
+ int index = 0;
+ deletePersistentAllBySingleStringQuery(ASSERTION_FAILED,
+ VALID_QUERIES[index], parameters[index], 1);
+ }
+
+ /** */
+ public void testNegative() {
+ for (int i = 0; i < INVALID_QUERIES.length; i++) {
+ deletePersistentAllByAPIQuery(ASSERTION_FAILED,
+ INVALID_QUERIES[i], null, -1);
+ deletePersistentAllBySingleStringQuery(ASSERTION_FAILED,
+ INVALID_QUERIES[i], null, -1);
+ }
+ }
+
+ /**
+ * @see JDO_Test#localSetUp()
+ */
+ protected void localSetUp() {
+ loadCompanyModel(getPM(), COMPANY_TESTDATA);
+ addTearDownClass(CompanyModelReader.getTearDownClasses());
+ }
+}
|