db-jdo-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bra...@apache.org
Subject svn commit: r350282 - in /incubator/jdo/trunk/tck20/test: conf/ java/org/apache/jdo/tck/query/ java/org/apache/jdo/tck/query/delete/
Date Thu, 01 Dec 2005 17:30:43 GMT
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());
+    }
+}



Mime
View raw message