diff options
| author | Brian S. O'Neill <bronee@gmail.com> | 2007-10-14 02:31:22 +0000 | 
|---|---|---|
| committer | Brian S. O'Neill <bronee@gmail.com> | 2007-10-14 02:31:22 +0000 | 
| commit | 1b10ed688bd75f7c2535bab96c5ff705a5df314e (patch) | |
| tree | 331de5ce019a02855c42ce15a320aba5b70c1ce5 /src | |
| parent | 14aa48fbc0f6275b15f8da5cbad7948c4fd9f08c (diff) | |
Added support for "where exists" in queries via new syntax.
Diffstat (limited to 'src')
4 files changed, 576 insertions, 20 deletions
diff --git a/src/test/java/com/amazon/carbonado/cursor/TestFilteredCursor.java b/src/test/java/com/amazon/carbonado/cursor/TestFilteredCursor.java index 82854c2..2279e9b 100644 --- a/src/test/java/com/amazon/carbonado/cursor/TestFilteredCursor.java +++ b/src/test/java/com/amazon/carbonado/cursor/TestFilteredCursor.java @@ -22,6 +22,8 @@ import java.util.Arrays;  import java.util.Iterator;
  import java.util.List;
 +import org.joda.time.DateTime;
 +
  import junit.framework.TestCase;
  import junit.framework.TestSuite;
 @@ -29,6 +31,7 @@ import com.amazon.carbonado.*;  import com.amazon.carbonado.filter.*;
  import com.amazon.carbonado.repo.toy.ToyRepository;
 +import com.amazon.carbonado.stored.*;
  /**
   * 
 @@ -386,6 +389,350 @@ public class TestFilteredCursor extends TestCase {          assertEquals(expected.length, actualCount);
      }
 +    public void testExistsNoParams() throws Exception {
 +        Repository repo = new ToyRepository();
 +        Storage<Order> orders = repo.storageFor(Order.class);
 +        Storage<OrderItem> items = repo.storageFor(OrderItem.class);
 +        Storage<Shipment> shipments = repo.storageFor(Shipment.class);
 +
 +        Order order = orders.prepare();
 +        order.setOrderID(1);
 +        order.setOrderNumber("one");
 +        order.setOrderTotal(100);
 +        order.setAddressID(0);
 +        order.insert();
 +
 +        // Query for orders with any items.
 +        long count = orders.query("orderItems()").count();
 +        assertEquals(0, count);
 +
 +        // Query for orders with no items.
 +        List<Order> matches = orders.query("!orderItems()").fetch().toList();
 +        assertEquals(1, matches.size());
 +        assertEquals(order, matches.get(0));
 +
 +        // Query for orders with any shipments with any items.
 +        matches = orders.query("shipments(orderItems())").fetch().toList();
 +        assertEquals(0, matches.size());
 +
 +        // Query for orders with no shipments with any items.
 +        matches = orders.query("!shipments(orderItems())").fetch().toList();
 +        assertEquals(1, matches.size());
 +
 +        // Query for orders with any shipments with no items.
 +        matches = orders.query("shipments(!orderItems())").fetch().toList();
 +        assertEquals(0, matches.size());
 +
 +        // Query for orders with no shipments with no items.
 +        matches = orders.query("!shipments(!orderItems())").fetch().toList();
 +        assertEquals(1, matches.size());
 +
 +        // Insert more records (orders with items) and re-issue queries.
 +
 +        order = orders.prepare();
 +        order.setOrderID(2);
 +        order.setOrderNumber("two");
 +        order.setOrderTotal(200);
 +        order.setAddressID(0);
 +        order.insert();
 +
 +        OrderItem item = items.prepare();
 +        item.setOrderItemID(1);
 +        item.setOrderID(2);
 +        item.setItemDescription("desc one");
 +        item.setItemQuantity(1);
 +        item.setItemPrice(100);
 +        item.setShipmentID(0);
 +        item.insert();
 +
 +        // Query for orders with any items.
 +        matches = orders.query("orderItems()").fetch().toList();
 +        assertEquals(1, matches.size());
 +        assertEquals(2, matches.get(0).getOrderID());
 +
 +        // Query for orders with no items.
 +        matches = orders.query("!orderItems()").fetch().toList();
 +        assertEquals(1, matches.size());
 +        assertEquals(1, matches.get(0).getOrderID());
 +
 +        // Query for orders with any shipments with any items.
 +        matches = orders.query("shipments(orderItems())").fetch().toList();
 +        assertEquals(0, matches.size());
 +
 +        // Query for orders with no shipments with any items.
 +        matches = orders.query("!shipments(orderItems())").fetch().toList();
 +        assertEquals(2, matches.size());
 +        assertEquals(1, matches.get(0).getOrderID());
 +        assertEquals(2, matches.get(1).getOrderID());
 +
 +        // Query for orders with any shipments with no items.
 +        matches = orders.query("shipments(!orderItems())").fetch().toList();
 +        assertEquals(0, matches.size());
 +
 +        // Query for orders with no shipments with no items.
 +        matches = orders.query("!shipments(!orderItems())").fetch().toList();
 +        assertEquals(2, matches.size());
 +
 +        // Insert more records (orders with shipments with items) and re-issue queries.
 +
 +        order = orders.prepare();
 +        order.setOrderID(3);
 +        order.setOrderNumber("three");
 +        order.setOrderTotal(300);
 +        order.setAddressID(0);
 +        order.insert();
 +
 +        Shipment shipment = shipments.prepare();
 +        shipment.setShipmentID(1);
 +        shipment.setShipmentNotes("notes");
 +        shipment.setShipmentDate(new DateTime());
 +        shipment.setOrderID(3);
 +        shipment.setShipperID(0);
 +        shipment.insert();
 +
 +        item = items.prepare();
 +        item.setOrderItemID(2);
 +        item.setOrderID(3);
 +        item.setItemDescription("desc two");
 +        item.setItemQuantity(1);
 +        item.setItemPrice(500);
 +        item.setShipmentID(1);
 +        item.insert();
 +
 +        // Query for orders with any items.
 +        matches = orders.query("orderItems()").fetch().toList();
 +        assertEquals(2, matches.size());
 +        assertEquals(2, matches.get(0).getOrderID());
 +        assertEquals(3, matches.get(1).getOrderID());
 +
 +        // Query for orders with no items.
 +        matches = orders.query("!orderItems()").fetch().toList();
 +        assertEquals(1, matches.size());
 +        assertEquals(1, matches.get(0).getOrderID());
 +
 +        // Query for orders with any shipments with any items.
 +        matches = orders.query("shipments(orderItems())").fetch().toList();
 +        assertEquals(1, matches.size());
 +        assertEquals(3, matches.get(0).getOrderID());
 +
 +        // Query for orders with no shipments with any items.
 +        matches = orders.query("!shipments(orderItems())").fetch().toList();
 +        assertEquals(2, matches.size());
 +        assertEquals(1, matches.get(0).getOrderID());
 +        assertEquals(2, matches.get(1).getOrderID());
 +
 +        // Query for orders with any shipments with no items.
 +        matches = orders.query("shipments(!orderItems())").fetch().toList();
 +        assertEquals(0, matches.size());
 +
 +        // Query for orders with no shipments with no items.
 +        matches = orders.query("!shipments(!orderItems())").fetch().toList();
 +        assertEquals(3, matches.size());
 +
 +        // Insert more records to test for empty shipments.
 +
 +        order = orders.prepare();
 +        order.setOrderID(4);
 +        order.setOrderNumber("four");
 +        order.setOrderTotal(400);
 +        order.setAddressID(0);
 +        order.insert();
 +
 +        shipment = shipments.prepare();
 +        shipment.setShipmentID(2);
 +        shipment.setShipmentNotes("notes 2");
 +        shipment.setShipmentDate(new DateTime());
 +        shipment.setOrderID(4);
 +        shipment.setShipperID(0);
 +        shipment.insert();
 +
 +        // Query for orders with any shipments with no items.
 +        matches = orders.query("shipments(!orderItems())").fetch().toList();
 +        assertEquals(1, matches.size());
 +        assertEquals(4, matches.get(0).getOrderID());
 +
 +        // Query for orders with no shipments with no items.
 +        matches = orders.query("!shipments(!orderItems())").fetch().toList();
 +        assertEquals(3, matches.size());
 +        assertEquals(1, matches.get(0).getOrderID());
 +        assertEquals(2, matches.get(1).getOrderID());
 +        assertEquals(3, matches.get(2).getOrderID());
 +    }
 +
 +    public void testExistsWithParams() throws Exception {
 +        Repository repo = new ToyRepository();
 +        Storage<Order> orders = repo.storageFor(Order.class);
 +        Storage<OrderItem> items = repo.storageFor(OrderItem.class);
 +        Storage<Shipment> shipments = repo.storageFor(Shipment.class);
 +
 +        Order order = orders.prepare();
 +        order.setOrderID(1);
 +        order.setOrderNumber("one");
 +        order.setOrderTotal(100);
 +        order.setAddressID(0);
 +        order.insert();
 +
 +        Shipment shipment = shipments.prepare();
 +        shipment.setShipmentID(1);
 +        shipment.setShipmentNotes("notes 1");
 +        shipment.setShipmentDate(new DateTime());
 +        shipment.setOrderID(1);
 +        shipment.setShipperID(0);
 +        shipment.insert();
 +
 +        shipment = shipments.prepare();
 +        shipment.setShipmentID(2);
 +        shipment.setShipmentNotes("notes 2");
 +        shipment.setShipmentDate(new DateTime());
 +        shipment.setOrderID(1);
 +        shipment.setShipperID(0);
 +        shipment.insert();
 +
 +        OrderItem item = items.prepare();
 +        item.setOrderItemID(1);
 +        item.setOrderID(1);
 +        item.setItemDescription("one one");
 +        item.setItemQuantity(1);
 +        item.setItemPrice(500);
 +        item.setShipmentID(1);
 +        item.insert();
 +
 +        item = items.prepare();
 +        item.setOrderItemID(2);
 +        item.setOrderID(1);
 +        item.setItemDescription("one two");
 +        item.setItemQuantity(1);
 +        item.setItemPrice(500);
 +        item.setShipmentID(1);
 +        item.insert();
 +
 +        item = items.prepare();
 +        item.setOrderItemID(3);
 +        item.setOrderID(1);
 +        item.setItemDescription("one three");
 +        item.setItemQuantity(2);
 +        item.setItemPrice(500);
 +        item.setShipmentID(2);
 +        item.insert();
 +
 +        order = orders.prepare();
 +        order.setOrderID(2);
 +        order.setOrderNumber("two");
 +        order.setOrderTotal(20000);
 +        order.setAddressID(0);
 +        order.insert();
 +
 +        order = orders.prepare();
 +        order.setOrderID(3);
 +        order.setOrderNumber("three");
 +        order.setOrderTotal(300);
 +        order.setAddressID(0);
 +        order.insert();
 +
 +        item = items.prepare();
 +        item.setOrderItemID(4);
 +        item.setOrderID(3);
 +        item.setItemDescription("three one");
 +        item.setItemQuantity(20);
 +        item.setItemPrice(500);
 +        item.setShipmentID(2);
 +        item.insert();
 +
 +        order = orders.prepare();
 +        order.setOrderID(4);
 +        order.setOrderNumber("four");
 +        order.setOrderTotal(0);
 +        order.setAddressID(0);
 +        order.insert();
 +
 +        shipment = shipments.prepare();
 +        shipment.setShipmentID(3);
 +        shipment.setShipmentNotes("notes 3");
 +        shipment.setShipmentDate(new DateTime());
 +        shipment.setOrderID(4);
 +        shipment.setShipperID(0);
 +        shipment.insert();
 +
 +        item = items.prepare();
 +        item.setOrderItemID(5);
 +        item.setOrderID(4);
 +        item.setItemDescription("four one");
 +        item.setItemQuantity(99);
 +        item.setItemPrice(500);
 +        item.setShipmentID(3);
 +        item.insert();
 +
 +        // Query for orders which has an item with a specific quantity.
 +
 +        List<Order> matches = orders.query("orderItems(itemQuantity >= ? & itemQuantity < ?)")
 +            .with(2).with(10).fetch().toList();
 +        assertEquals(1, matches.size());
 +        assertEquals(1, matches.get(0).getOrderID());
 +
 +        matches = orders.query("orderItems(itemQuantity >= ? & itemQuantity < ?)")
 +            .with(2).with(50).fetch().toList();
 +        assertEquals(2, matches.size());
 +        assertEquals(1, matches.get(0).getOrderID());
 +        assertEquals(3, matches.get(1).getOrderID());
 +
 +        // Query for empty orders with a non-zero total.
 +
 +        matches = orders.query("orderTotal != ? & !orderItems()")
 +            .with(0).fetch().toList();
 +        assertEquals(1, matches.size());
 +        assertEquals(2, matches.get(0).getOrderID());
 +            
 +        matches = orders.query("!orderItems() & orderTotal != ?")
 +            .with(0).fetch().toList();
 +        assertEquals(1, matches.size());
 +        assertEquals(2, matches.get(0).getOrderID());
 +
 +        // Query for non-empty orders or those with a zero total.
 +
 +        matches = orders.query("!(!orderItems() & orderTotal != ?)")
 +            .with(0).fetch().toList();
 +        assertEquals(3, matches.size());
 +        for (int i=0; i<matches.size(); i++) {
 +            assertTrue(matches.get(i).getOrderID() != 2);
 +        }
 +
 +        // Query for orders in shipments which have an item with a high quantity.
 +
 +        matches = orders.query("shipments(orderItems(itemQuantity > ?))")
 +            .with(10).fetch().toList();
 +        assertEquals(2, matches.size());
 +        assertEquals(1, matches.get(0).getOrderID());
 +        assertEquals(4, matches.get(1).getOrderID());
 +
 +        // Query with a specific quantity.
 +
 +        matches = orders.query("shipments(orderItems(itemQuantity = ?))")
 +            .with(99).fetch().toList();
 +        assertEquals(1, matches.size());
 +        assertEquals(4, matches.get(0).getOrderID());
 +
 +        // Mix in some more stuff...
 +
 +        matches = orders
 +            .query("orderNumber = ? | shipments(orderItems(itemQuantity = ?) | shipmentNotes = ?)")
 +            .with("three").with(99).with("notes 1").fetch().toList();
 +        assertEquals(3, matches.size());
 +        assertEquals(1, matches.get(0).getOrderID());
 +        assertEquals(3, matches.get(1).getOrderID());
 +        assertEquals(4, matches.get(2).getOrderID());
 +
 +        matches = orders
 +            .query("orderNumber = ? | " +
 +                   "shipments(orderItems(itemQuantity = ?) | " +
 +                              "shipmentNotes = ? | " +
 +                              "orderItems(itemQuantity = ?))")
 +            .with("three").with(99).with("notes 1").with(25).fetch().toList();
 +        assertEquals(3, matches.size());
 +        assertEquals(1, matches.get(0).getOrderID());
 +        assertEquals(3, matches.get(1).getOrderID());
 +        assertEquals(4, matches.get(2).getOrderID());
 +    }
 +
      @PrimaryKey("ID")
      public static interface FloatRecord extends Storable {
          int getID();
 diff --git a/src/test/java/com/amazon/carbonado/cursor/TestShortCircuitOptimizer.java b/src/test/java/com/amazon/carbonado/cursor/TestShortCircuitOptimizer.java index 3e926a3..6bc62a6 100644 --- a/src/test/java/com/amazon/carbonado/cursor/TestShortCircuitOptimizer.java +++ b/src/test/java/com/amazon/carbonado/cursor/TestShortCircuitOptimizer.java @@ -159,11 +159,10 @@ public class TestShortCircuitOptimizer extends TestCase {          }
      }
 -    /*
      public void testOneToManyJoins() throws Exception {
          {
              Filter<Order> filter = Filter
 -                .filterFor(Order.class, "orderNumber = ? & orderItems.itemPrice = ?");
 +                .filterFor(Order.class, "orderNumber = ? & orderItems(itemPrice = ?)");
              Filter<Order> optimized = ShortCircuitOptimizer.optimize(filter);
              // No change.
 @@ -172,48 +171,45 @@ public class TestShortCircuitOptimizer extends TestCase {          {
              Filter<Order> filter = Filter
 -                .filterFor(Order.class, "orderItems.itemPrice = ? & orderNumber = ?");
 +                .filterFor(Order.class, "orderItems(itemPrice = ?) & orderNumber = ?");
              Filter<Order> optimized = ShortCircuitOptimizer.optimize(filter);
              assertEquals(Filter.filterFor
 -                         (Order.class, "orderNumber = ? & orderItems.itemPrice = ?"),
 +                         (Order.class, "orderNumber = ? & orderItems(itemPrice = ?)"),
                           optimized);
          }
          {
              Filter<Order> filter = Filter
                  .filterFor(Order.class,
 -                           "(orderItems.itemPrice = ? & orderNumber = ?) | orderTotal < ?");
 +                           "(orderItems(itemPrice = ?) & orderNumber = ?) | orderTotal < ?");
              Filter<Order> optimized = ShortCircuitOptimizer.optimize(filter);
              assertEquals(Filter.filterFor
                           (Order.class,
 -                          "orderTotal < ? | (orderNumber = ? & orderItems.itemPrice = ?)"),
 +                          "orderTotal < ? | (orderNumber = ? & orderItems(itemPrice = ?))"),
                           optimized);
          }
          {
              Filter<Order> filter = Filter
                  .filterFor(Order.class,
 -                           "orderItems.shipment.shipmentDate > ? | shipments.shipmentDate < ?");
 +                           "orderItems(shipment.shipmentDate > ?) | shipments(shipmentDate < ?)");
              Filter<Order> optimized = ShortCircuitOptimizer.optimize(filter);
 -            assertEquals(Filter.filterFor
 -                         (Order.class,
 -                          "shipments.shipmentDate < ? | orderItems.shipment.shipmentDate > ?"),
 -                         optimized);
 +            // No change because optimizer doesn't consider complexity of sub-filters.
 +            assertEquals(filter, optimized);
          }
          {
              Filter<Order> filter = Filter
                  .filterFor
                  (Order.class,
 -                 "orderItems.shipment.shipmentDate > ? | shipments.shipper.shipperName != ?");
 +                 "orderItems(shipment.shipmentDate > ?) | shipments(shipper.shipperName != ?)");
              Filter<Order> optimized = ShortCircuitOptimizer.optimize(filter);
              // No change.
              assertEquals(filter, optimized);
          }
      }
 -    */
  }
 diff --git a/src/test/java/com/amazon/carbonado/filter/TestFilterExists.java b/src/test/java/com/amazon/carbonado/filter/TestFilterExists.java new file mode 100644 index 0000000..e454d47 --- /dev/null +++ b/src/test/java/com/amazon/carbonado/filter/TestFilterExists.java @@ -0,0 +1,209 @@ +/*
 + * Copyright 2007 Amazon Technologies, Inc. or its affiliates.
 + * Amazon, Amazon.com and Carbonado are trademarks or registered trademarks
 + * of Amazon Technologies, Inc. or its affiliates.  All rights reserved.
 + *
 + * 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 com.amazon.carbonado.filter;
 +
 +import junit.framework.TestCase;
 +import junit.framework.TestSuite;
 +
 +import com.amazon.carbonado.MalformedFilterException;
 +import com.amazon.carbonado.stored.*;
 +
 +/**
 + * 
 + *
 + * @author Brian S O'Neill
 + */
 +public class TestFilterExists extends TestCase {
 +    public static void main(String[] args) {
 +        junit.textui.TestRunner.run(suite());
 +    }
 +
 +    public static TestSuite suite() {
 +        return new TestSuite(TestFilterExists.class);
 +    }
 +
 +    public TestFilterExists(String name) {
 +        super(name);
 +    }
 +
 +    public void testParsing() {
 +        {
 +            Filter<Order> f1 = Filter.filterFor(Order.class, "shipments()");
 +            assertTrue(f1 instanceof ExistsFilter);
 +            assertEquals("shipments", ((ExistsFilter) f1).getChainedProperty().toString());
 +            assertTrue(((ExistsFilter) f1).getSubFilter().isOpen());
 +        }
 +
 +        {
 +            Filter<Order> f1 = Filter.filterFor(Order.class, "orderTotal = ? & shipments()");
 +            assertTrue(f1 instanceof AndFilter);
 +            Filter left = ((AndFilter) f1).getLeftFilter();
 +            Filter right = ((AndFilter) f1).getRightFilter();
 +            assertTrue(Filter.filterFor(Order.class, "orderTotal = ?") == left);
 +            assertTrue(Filter.filterFor(Order.class, "shipments()") == right);
 +        }
 +
 +        {
 +            Filter<Order> f1 = Filter.filterFor(Order.class, "shipments() | orderTotal = ?");
 +            assertTrue(f1 instanceof OrFilter);
 +            Filter left = ((OrFilter) f1).getLeftFilter();
 +            Filter right = ((OrFilter) f1).getRightFilter();
 +            assertTrue(Filter.filterFor(Order.class, "shipments()") == left);
 +            assertTrue(Filter.filterFor(Order.class, "orderTotal = ?") == right);
 +        }
 +
 +        {
 +            Filter<Order> f1 = Filter.filterFor(Order.class, "shipments(shipmentNotes=?)");
 +            assertTrue(f1 instanceof ExistsFilter);
 +            assertEquals("shipments", ((ExistsFilter) f1).getChainedProperty().toString());
 +            assertTrue(Filter.filterFor(Shipment.class, "shipmentNotes = ?")
 +                       == ((ExistsFilter) f1).getSubFilter());
 +        }
 +
 +        {
 +            Filter<Order> f1 = Filter.filterFor(Order.class, "shipments(orderItems(itemPrice=?))");
 +            assertTrue(f1 instanceof ExistsFilter);
 +            assertEquals("shipments", ((ExistsFilter) f1).getChainedProperty().toString());
 +            Filter sub = ((ExistsFilter) f1).getSubFilter();
 +            assertTrue(sub instanceof ExistsFilter);
 +            assertTrue(Filter.filterFor(OrderItem.class, "itemPrice = ?")
 +                       == ((ExistsFilter) sub).getSubFilter());
 +        }
 +
 +        {
 +            Filter<Shipment> f1 = Filter.filterFor
 +                (Shipment.class, "order.shipments(orderItems(itemPrice=?))");
 +            assertTrue(f1 instanceof ExistsFilter);
 +            assertEquals("order.shipments", ((ExistsFilter) f1).getChainedProperty().toString());
 +            Filter sub = ((ExistsFilter) f1).getSubFilter();
 +            assertTrue(sub instanceof ExistsFilter);
 +            assertTrue(Filter.filterFor(OrderItem.class, "itemPrice = ?")
 +                       == ((ExistsFilter) sub).getSubFilter());
 +        }
 +    }
 +
 +    public void testParseErrors() {
 +        try {
 +            Filter.filterFor(Order.class, "address()");
 +            fail();
 +        } catch (MalformedFilterException e) {
 +        }
 +
 +        try {
 +            Filter.filterFor(Order.class, "shipments");
 +            fail();
 +        } catch (MalformedFilterException e) {
 +        }
 +
 +        try {
 +            Filter.filterFor(Order.class, "shipments(");
 +            fail();
 +        } catch (MalformedFilterException e) {
 +        }
 +
 +        try {
 +            Filter.filterFor(Order.class, "shipments(orderTotal=?)");
 +            fail();
 +        } catch (MalformedFilterException e) {
 +        }
 +    }
 +
 +    public void testVisitor() {
 +        Filter<Order> f1 = Filter.filterFor
 +            (Order.class, "orderTotal = ? & shipments(orderItems(itemPrice=?)) | orderTotal < ?");
 +        Filter<Order> f2 = Filter.filterFor(Order.class, "shipments(orderItems(itemPrice=?))");
 +
 +        class TestVisitor extends Visitor {
 +            ExistsFilter f;
 +
 +            public Object visit(ExistsFilter f, Object param) {
 +                if (this.f != null) {
 +                    fail();
 +                }
 +                this.f = f;
 +                return null;
 +            }
 +        }
 +
 +        TestVisitor tv = new TestVisitor();
 +        f1.accept(tv, null);
 +
 +        assertTrue(f2 == tv.f);
 +    }
 +
 +    public void testBindingAndValues() {
 +        Filter<Order> f1 = Filter.filterFor
 +            (Order.class,
 +             "orderComments != ? & " +
 +             "((shipments(orderItems(itemPrice=? & (itemPrice=? | itemPrice>?)) | " +
 +             "order.shipments(orderItems(itemPrice=?)))) | orderComments!=?)");
 +
 +        assertTrue(f1 != f1.bind());
 +        assertTrue(f1.bind() != f1.disjunctiveNormalForm());
 +
 +        FilterValues<Order> fv = f1.initialFilterValues();
 +        assertEquals(6, fv.getBlankParameterCount());
 +
 +        fv = fv.with("comments1");
 +        assertEquals(5, fv.getBlankParameterCount());
 +        assertEquals("comments1", fv.getSuppliedValues()[0]);
 +
 +        fv = fv.with(100);
 +        assertEquals(4, fv.getBlankParameterCount());
 +        assertEquals("comments1", fv.getSuppliedValues()[0]);
 +        assertEquals(100, fv.getSuppliedValues()[1]);
 +
 +        fv = fv.with(200);
 +        assertEquals(3, fv.getBlankParameterCount());
 +        assertEquals("comments1", fv.getSuppliedValues()[0]);
 +        assertEquals(100, fv.getSuppliedValues()[1]);
 +        assertEquals(200, fv.getSuppliedValues()[2]);
 +
 +        fv = fv.with(300);
 +        assertEquals(2, fv.getBlankParameterCount());
 +        assertEquals("comments1", fv.getSuppliedValues()[0]);
 +        assertEquals(100, fv.getSuppliedValues()[1]);
 +        assertEquals(200, fv.getSuppliedValues()[2]);
 +        assertEquals(300, fv.getSuppliedValues()[3]);
 +
 +        fv = fv.with(400);
 +        assertEquals(1, fv.getBlankParameterCount());
 +        assertEquals("comments1", fv.getSuppliedValues()[0]);
 +        assertEquals(100, fv.getSuppliedValues()[1]);
 +        assertEquals(200, fv.getSuppliedValues()[2]);
 +        assertEquals(300, fv.getSuppliedValues()[3]);
 +        assertEquals(400, fv.getSuppliedValues()[4]);
 +
 +        fv = fv.with("comments2");
 +        assertEquals(0, fv.getBlankParameterCount());
 +        assertEquals("comments1", fv.getSuppliedValues()[0]);
 +        assertEquals(100, fv.getSuppliedValues()[1]);
 +        assertEquals(200, fv.getSuppliedValues()[2]);
 +        assertEquals(300, fv.getSuppliedValues()[3]);
 +        assertEquals(400, fv.getSuppliedValues()[4]);
 +        assertEquals("comments2", fv.getSuppliedValues()[5]);
 +
 +        assertEquals("comments1", fv.getValues()[0]);
 +        assertEquals(100, fv.getValues()[1]);
 +        assertEquals(200, fv.getValues()[2]);
 +        assertEquals(300, fv.getValues()[3]);
 +        assertEquals(400, fv.getValues()[4]);
 +        assertEquals("comments2", fv.getValues()[5]);
 +    }
 +}
 diff --git a/src/test/java/com/amazon/carbonado/repo/toy/ToyStorage.java b/src/test/java/com/amazon/carbonado/repo/toy/ToyStorage.java index 34c33a5..ec03fad 100644 --- a/src/test/java/com/amazon/carbonado/repo/toy/ToyStorage.java +++ b/src/test/java/com/amazon/carbonado/repo/toy/ToyStorage.java @@ -95,7 +95,7 @@ public class ToyStorage<S extends Storable>      }
      public Query<S> query() {
 -        return new ToyQuery(null, null, null);
 +        return new ToyQuery(null, null, null, null);
      }
      public Query<S> query(String filter) {
 @@ -103,11 +103,11 @@ public class ToyStorage<S extends Storable>      }
      public Query<S> query(Filter<S> filter) {
 -        return new ToyQuery(filter.initialFilterValues(), null, null);
 +        return new ToyQuery(filter, null, null, null);
      }
 -    public Query<S> query(FilterValues<S> values, OrderingList<S> ordering) {
 -        return new ToyQuery(values, ordering, null);
 +    public Query<S> query(Filter<S> filter, FilterValues<S> values, OrderingList<S> ordering) {
 +        return new ToyQuery(filter, values, ordering, null);
      }
      public QueryExecutor<S> executor(Filter<S> filter, OrderingList<S> ordering) {
 @@ -259,8 +259,12 @@ public class ToyStorage<S extends Storable>      }
      private class ToyQuery extends StandardQuery<S> {
 -        ToyQuery(FilterValues<S> values, OrderingList<S> ordering, QueryExecutor<S> executor) {
 -            super(values, ordering, executor);
 +        ToyQuery(Filter<S> filter,
 +                 FilterValues<S> values,
 +                 OrderingList<S> ordering,
 +                 QueryExecutor<S> executor)
 +        {
 +            super(filter, values, ordering, executor);
          }
          protected Transaction enterTransaction(IsolationLevel level) {
 @@ -279,7 +283,7 @@ public class ToyStorage<S extends Storable>                                                 OrderingList<S> ordering,
                                                 QueryExecutor<S> executor)
          {
 -            return new ToyQuery(values, ordering, executor);
 +            return new ToyQuery(values.getFilter(), values, ordering, executor);
          }
      }
  }
  | 
