@@ -12,9 +12,9 @@ r21: { | |||
fixes: | |||
- Return null NPE in selectFirst() if list is empty (pr-5) | |||
- Fix Moxie toolkit download URL (pr-6) | |||
- Be more careful with primitive numeric type rollovers | |||
- Be more careful with primitive numeric type rollovers (pr-6) | |||
changes: | |||
- Revised EnumId interface to support generic types | |||
- Revised EnumId interface to support generic types (pr-6) | |||
additions: | |||
- Add syntax for IN and NOT IN (pr-7) | |||
- Add support for nested AND/OR conditions (pr-8) |
@@ -67,7 +67,7 @@ can be used for all iciql expressions | |||
<td>INT<br/><em>EnumType.ORDINAL</em><br/><i>can only <b>declare and explicitly reference</b> one instance of <u>each enum type</u> per model<br/>multiple instances of an enum type within a model is allowed if not using where/set/on/and/or/groupBy/orderBy(enum)</i></td></tr> | |||
<tr><td>java.lang.Enum implements<br/><em>com.iciql.Iciql.EnumId.enumId()</em></td><td> </td> | |||
<td>INT<br/><em>EnumType.ENUMID</em><br/><i>can only <b>declare and explicitly reference</b> one instance of <u>each enum type</u> per model<br/>multiple instances of an enum type within a model is allowed if not using where/set/on/and/or/groupBy/orderBy(enum)</i></td></tr> | |||
<td><i>variable</i><br/><em>EnumType.ENUMID</em><br/><i>can only <b>declare and explicitly reference</b> one instance of <u>each enum type</u> per model<br/>multiple instances of an enum type within a model is allowed if not using where/set/on/and/or/groupBy/orderBy(enum)</i></td></tr> | |||
<tr><td colspan="3"><b>Partially Supported Types</b><br/> | |||
can not be directly referenced in an expression</td></tr> | |||
@@ -383,4 +383,4 @@ public class Product { | |||
public Product() { | |||
} | |||
} | |||
---JAVA--- | |||
---JAVA--- |
@@ -69,6 +69,44 @@ List<Product> allProducts = db.buildObjects(Product.class, rs); | |||
JdbcUtils.closeSilently(rs, true); | |||
---JAVA--- | |||
### Compound Conditions | |||
It is possible to specify type-safe compound where clauses using nested `And` and `Or` statements. | |||
---JAVA--- | |||
final Customer model = new Customer(); | |||
List<Customer> regionals = | |||
db.from(model).where(model.customerId).isNotNull() | |||
.and(model.region).isNotNull() | |||
.and(new Or<Customer>(db, model) {{ | |||
or(model.region).is("LA"); | |||
or(model.region).is("CA"); | |||
}}); | |||
List<Customer> regionalType1s = | |||
db.from(model).where(new And<Customer>(db, model) {{ | |||
and(model.type).is(1); | |||
and(new Or<Customer>(db, model) {{ | |||
or(model.region).is("CA"); | |||
or(model.region).is("LA"); | |||
}}); | |||
}}); | |||
---JAVA--- | |||
### Finding Matches for a List of Values | |||
You can use SQL's *IN* WHERE clause with the `oneOf` or `noneOf` conditions. | |||
---JAVA--- | |||
final Customer model = new Customer(); | |||
List<Customer> regionals = db.from(model).where(model.region).oneOf("CA", "LA"); | |||
List<Customer> others = db.from(model).where(model.region).noneOf("CA", "LA"); | |||
---JAVA--- | |||
### Read-only Views | |||
View model classes can inherit their field definitions from a parent table model class. | |||
@@ -232,4 +270,4 @@ for (int i = 0; i < 5; i++) { | |||
---JAVA--- | |||
</td></tr> | |||
</table> | |||
</table> |
@@ -93,7 +93,7 @@ import com.iciql.util.Utils; | |||
@SuiteClasses({ AliasMapTest.class, AnnotationsTest.class, BooleanModelTest.class, ClobTest.class, | |||
ConcurrencyTest.class, EnumsTest.class, ModelsTest.class, PrimitivesTest.class, OneOfTest.class, | |||
RuntimeQueryTest.class, SamplesTest.class, UpdateTest.class, UpgradesTest.class, JoinTest.class, | |||
UUIDTest.class, ViewsTest.class, ForeignKeyTest.class, TransactionTest.class, StackableConditionsTest.class }) | |||
UUIDTest.class, ViewsTest.class, ForeignKeyTest.class, TransactionTest.class, NestedConditionsTest.class }) | |||
public class IciqlSuite { | |||
private static final TestDb[] TEST_DBS = { |
@@ -20,6 +20,10 @@ package com.iciql.test; | |||
import static org.junit.Assert.assertEquals; | |||
import static org.junit.Assert.assertTrue; | |||
import java.util.List; | |||
import java.util.Set; | |||
import java.util.TreeSet; | |||
import org.junit.After; | |||
import org.junit.Before; | |||
import org.junit.Test; | |||
@@ -31,7 +35,7 @@ import com.iciql.IciqlException; | |||
import com.iciql.QueryWhere; | |||
import com.iciql.test.models.Customer; | |||
public class StackableConditionsTest { | |||
public class NestedConditionsTest { | |||
enum Region { | |||
JP, FR | |||
@@ -42,6 +46,7 @@ public class StackableConditionsTest { | |||
@Before | |||
public void setUp() { | |||
db = IciqlSuite.openNewDb(); | |||
db.insertAll(Customer.getList()); | |||
} | |||
@After | |||
@@ -68,9 +73,8 @@ public class StackableConditionsTest { | |||
return query.toSQL(); | |||
} | |||
@SuppressWarnings("serial") | |||
@Test | |||
public void andOrTest() { | |||
public void andOrSyntaxTest() { | |||
String Customer = db.getDialect().prepareTableName(null, "Customer"); | |||
String customerId = db.getDialect().prepareColumnName("customerId"); | |||
String region = db.getDialect().prepareColumnName("region"); | |||
@@ -155,7 +159,7 @@ public class StackableConditionsTest { | |||
} | |||
@Test | |||
public void fluentTest() { | |||
public void fluentSyntaxTest() { | |||
String Customer = db.getDialect().prepareTableName(null, "Customer"); | |||
String customerId = db.getDialect().prepareColumnName("customerId"); | |||
String region = db.getDialect().prepareColumnName("region"); | |||
@@ -194,4 +198,25 @@ public class StackableConditionsTest { | |||
Customer, customerId, region, region, region)); | |||
} | |||
@Test | |||
public void compoundConditionsTest() { | |||
final Customer c = new Customer(); | |||
List<Customer> matches = db.from(c) | |||
.where(c.customerId).like("A%") | |||
.and(c.region).isNotNull() | |||
.and(new Or<Customer>(db, c) {{ | |||
or(c.region).is("LA"); | |||
or(c.region).is("CA"); | |||
}}).select(); | |||
assertEquals(2, matches.size()); | |||
Set<String> ids = new TreeSet<String>(); | |||
for (Customer customer : matches) { | |||
ids.add(customer.customerId); | |||
} | |||
assertEquals("[ANTON, ASLAN]", ids.toString()); | |||
} | |||
} |
@@ -20,6 +20,9 @@ package com.iciql.test; | |||
import static org.junit.Assert.assertEquals; | |||
import java.util.ArrayList; | |||
import java.util.List; | |||
import java.util.Set; | |||
import java.util.TreeSet; | |||
import org.junit.After; | |||
import org.junit.Before; | |||
@@ -36,6 +39,7 @@ public class OneOfTest { | |||
@Before | |||
public void setUp() { | |||
db = IciqlSuite.openNewDb(); | |||
db.insertAll(Customer.getList()); | |||
} | |||
@After | |||
@@ -45,7 +49,7 @@ public class OneOfTest { | |||
@SuppressWarnings("serial") | |||
@Test | |||
public void oneOfTest() { | |||
public void oneOfSyntaxTest() { | |||
String PrimitivesTest = db.getDialect().prepareTableName(null, "PrimitivesTest"); | |||
String Customer = db.getDialect().prepareTableName(null, "Customer"); | |||
String myInteger = db.getDialect().prepareColumnName("myInteger"); | |||
@@ -82,7 +86,7 @@ public class OneOfTest { | |||
@SuppressWarnings("serial") | |||
@Test | |||
public void noneOfTest() { | |||
public void noneOfSyntaxTest() { | |||
String PrimitivesTest = db.getDialect().prepareTableName(null, "PrimitivesTest"); | |||
String Customer = db.getDialect().prepareTableName(null, "Customer"); | |||
String myInteger = db.getDialect().prepareColumnName("myInteger"); | |||
@@ -117,4 +121,28 @@ public class OneOfTest { | |||
.toSQL()); | |||
} | |||
public void noneOfTest() { | |||
Customer c = new Customer(); | |||
List<Customer> meAndny = db.from(c).where(c.region).noneOf("WA", "CA", "LA").select(); | |||
assertEquals(2, meAndny.size()); | |||
Set<String> regions = new TreeSet<String>(); | |||
for (Customer customer : meAndny) { | |||
regions.add(customer.region); | |||
} | |||
assertEquals("[ME, NY]", regions.toString()); | |||
} | |||
public void oneOfTest() { | |||
Customer c = new Customer(); | |||
List<Customer> meAndny = db.from(c).where(c.region).oneOf("ME", "NY").select(); | |||
assertEquals(2, meAndny.size()); | |||
Set<String> regions = new TreeSet<String>(); | |||
for (Customer customer : meAndny) { | |||
regions.add(customer.region); | |||
} | |||
assertEquals("[ME, NY]", regions.toString()); | |||
} | |||
} |
@@ -44,14 +44,20 @@ public class Customer { | |||
this.region = region; | |||
} | |||
@Override | |||
public String toString() { | |||
return customerId; | |||
} | |||
public static List<Customer> getList() { | |||
Customer[] list = { new Customer("ALFKI", "WA"), new Customer("ANATR", "WA"), | |||
new Customer("ANTON", "CA") }; | |||
return Arrays.asList(list); | |||
return Arrays.asList( | |||
new Customer("ALFKI", "WA"), | |||
new Customer("ANATR", "WA"), | |||
new Customer("ASLAN", "CA"), | |||
new Customer("ANTON", "CA"), | |||
new Customer("BROWN", "LA"), | |||
new Customer("SMITH", "NY"), | |||
new Customer("JONES", "ME")); | |||
} | |||
} |