diff options
Diffstat (limited to 'src/test/java/com/iciql')
40 files changed, 5050 insertions, 0 deletions
diff --git a/src/test/java/com/iciql/test/AliasMapTest.java b/src/test/java/com/iciql/test/AliasMapTest.java new file mode 100644 index 0000000..092f38b --- /dev/null +++ b/src/test/java/com/iciql/test/AliasMapTest.java @@ -0,0 +1,139 @@ +/* + * Copyright 2004-2011 H2 Group. + * Copyright 2011 James Moger. + * + * 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.iciql.test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +import com.iciql.Db; +import com.iciql.IciqlException; +import com.iciql.test.models.PrimitivesModel; +import com.iciql.test.models.Product; +import com.iciql.util.Utils; + +/** + * Tests object and primitive alias referencing. + */ +public class AliasMapTest { + + /** + * Tests that columns (p.unitsInStock) are not compared by value with the + * value (9), but by reference (using an identity hash map). See + * http://code.google.com/p/h2database/issues/detail?id=119 + * + * @author d moebius at scoop dash gmbh dot de + */ + @Test + public void testObjectAliasMapping() throws Exception { + Db db = IciqlSuite.openNewDb(); + db.insertAll(Product.getList()); + + // baseline count is the next id value + long bc = Utils.COUNTER.get(); + // number of fields in primitives model class + // each from() call will increment Utils.COUNTER by this amount + int fc = Product.class.getFields().length; + + Product p = new Product(); + // This test confirms standard object referencing querying. + long count = db.from(p).where(p.productId).is(9).selectCount(); + assertEquals(1, count); + // Confirms that productId counter value is baseline counter value + assertEquals(bc, p.productId.intValue()); + try { + // This test compares "bc + fc" which is the counter value of + // unitsInStock assigned by Utils.newObject() after the 2nd pass + // through from(). + // + // Object fields map by REFERENCE, not value. + db.from(p).where(Long.valueOf(bc + fc).intValue()).is(9).orderBy(p.productId).select(); + assertTrue("Fail: object field is mapping by value.", false); + } catch (IciqlException e) { + assertEquals(IciqlException.CODE_UNMAPPED_FIELD, e.getIciqlCode()); + assertEquals(bc + 5, p.productId.intValue()); + } + + try { + // This test compares Integer(bc) which is the counter value of + // unitsInStock assigned by Utils.newObject() after the 3rd pass + // through from(). + // + // Object fields map by REFERENCE, not value. + db.from(p).where(Long.valueOf(bc).intValue()).is(9).orderBy(p.productId).select(); + assertTrue("Fail: object field is mapping by value.", false); + } catch (IciqlException e) { + assertEquals(IciqlException.CODE_UNMAPPED_FIELD, e.getIciqlCode()); + assertEquals(bc + (2 * fc), p.productId.intValue()); + } + + db.close(); + } + + /** + * Confirms that primitive aliases ARE mapped by value. + */ + @Test + public void testPrimitiveAliasMapping() throws Exception { + Db db = IciqlSuite.openNewDb(); + PrimitivesModel model = new PrimitivesModel(); + model.myLong = 100L; + db.insert(model); + model.myLong = 200L; + db.insert(model); + + // baseline count is the next id value + long bc = Utils.COUNTER.get(); + // number of fields in primitives model class + // each from() call will increment Utils.COUNTER by this amount + int fc = PrimitivesModel.class.getFields().length; + + PrimitivesModel p = new PrimitivesModel(); + // This test confirms standard primitive referencing querying. + long count = db.from(p).where(p.myLong).is(100L).selectCount(); + assertEquals(1, count); + // Confirms that myLong counter value is bc + assertEquals(bc, p.myLong); + try { + // This test compares "bc + fc" which is the counter value + // of myLong assigned by Utils.newObject() after the 2nd pass + // through from(). + // + // Primitive fields map by VALUE. + count = db.from(p).where(bc + fc).is(100L).selectCount(); + assertEquals(1, count); + assertEquals(bc + fc, p.myLong); + } catch (IciqlException e) { + assertTrue(e.getMessage(), false); + } + try { + // This test compares "bc" which was the counter value of + // myLong assigned by Utils.newObject() after the 1st pass + // through from(). "bc" is unmapped now and will throw an + // exception. + // + // Primitive fields map by VALUE. + db.from(p).where(bc).is(100L).select(); + } catch (IciqlException e) { + assertEquals(IciqlException.CODE_UNMAPPED_FIELD, e.getIciqlCode()); + assertEquals(bc + (2 * fc), p.myLong); + } + db.close(); + } +}
\ No newline at end of file diff --git a/src/test/java/com/iciql/test/AnnotationsTest.java b/src/test/java/com/iciql/test/AnnotationsTest.java new file mode 100644 index 0000000..6aa75ad --- /dev/null +++ b/src/test/java/com/iciql/test/AnnotationsTest.java @@ -0,0 +1,196 @@ +/* + * Copyright 2004-2011 H2 Group. + * Copyright 2011 James Moger. + * + * 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.iciql.test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.sql.DatabaseMetaData; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.List; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.iciql.Db; +import com.iciql.IciqlException; +import com.iciql.test.models.Product; +import com.iciql.test.models.ProductAnnotationOnly; +import com.iciql.test.models.ProductInheritedAnnotation; +import com.iciql.test.models.ProductMixedAnnotation; +import com.iciql.test.models.ProductNoCreateTable; +import com.iciql.util.Utils; + +/** + * Test annotation processing. + */ +public class AnnotationsTest { + + /** + * This object represents a database (actually a connection to the + * database). + */ + + private Db db; + + @Before + public void setUp() { + db = IciqlSuite.openNewDb(); + db.insertAll(Product.getList()); + db.insertAll(ProductAnnotationOnly.getList()); + db.insertAll(ProductMixedAnnotation.getList()); + } + + @After + public void tearDown() { + db.close(); + } + + @Test + public void testIndexCreation() throws SQLException { + // test indexes are created, and columns are in the right order + DatabaseMetaData meta = db.getConnection().getMetaData(); + String schema = IciqlSuite.getDefaultSchema(db); + boolean toUpper = meta.storesUpperCaseIdentifiers(); + boolean toLower = meta.storesLowerCaseIdentifiers(); + ResultSet rs = meta.getIndexInfo(null, prepName(schema, toUpper, toLower), + prepName("ANNOTATEDPRODUCT", toUpper, toLower), false, true); + + List<String> list = Utils.newArrayList(); + while (rs.next()) { + String col = rs.getString("COLUMN_NAME"); + String index = rs.getString("INDEX_NAME"); + list.add((col + ":" + index).toLowerCase()); + } + assertTrue(list.contains("name:annotatedproduct_idx_0")); + assertTrue(list.contains("cat:annotatedproduct_idx_0")); + assertTrue(list.contains("name:nameidx")); + } + + private String prepName(String name, boolean upper, boolean lower) { + if (name == null) { + return null; + } + if (upper) { + return name.toUpperCase(); + } else if (lower) { + return name.toLowerCase(); + } + return name; + } + + @Test + public void testProductAnnotationOnly() { + ProductAnnotationOnly p = new ProductAnnotationOnly(); + assertEquals(10, db.from(p).selectCount()); + + // test IQColumn.name="cat" + assertEquals(2, db.from(p).where(p.category).is("Beverages").selectCount()); + + // test IQTable.annotationsOnly=true + // public String unmappedField is ignored by iciql + try { + db.from(p).where(p.unmappedField).is("unmapped").selectCount(); + assertTrue("this should never execute", false); + } catch (IciqlException e) { + assertEquals(IciqlException.CODE_UNMAPPED_FIELD, e.getIciqlCode()); + } + + // 10 objects, 10 autoIncremented unique values + assertEquals(10, db.from(p).selectDistinct(p.productName).size()); + + // test IQTable.primaryKey=id + try { + db.insertAll(ProductAnnotationOnly.getList()); + } catch (IciqlException e) { + assertEquals(IciqlException.CODE_DUPLICATE_KEY, e.getIciqlCode()); + } + } + + @Test + public void testProductMixedAnnotation() { + ProductMixedAnnotation p = new ProductMixedAnnotation(); + + // test IQColumn.name="cat" + assertEquals(2, db.from(p).where(p.category).is("Beverages").selectCount()); + + // test IQTable.annotationsOnly=false + // public String mappedField is reflectively mapped by iciql + assertEquals(10, db.from(p).where(p.mappedField).is("mapped").selectCount()); + + // test IQIgnore annotation + assertEquals(null, db.from(p).selectFirst().productDescription); + + // test IQColumn.primaryKey=true + try { + db.insertAll(ProductMixedAnnotation.getList()); + } catch (IciqlException e) { + assertEquals(IciqlException.CODE_DUPLICATE_KEY, e.getIciqlCode()); + } + } + + @Test + public void testTrimStringAnnotation() { + ProductAnnotationOnly p = new ProductAnnotationOnly(); + ProductAnnotationOnly prod = db.from(p).selectFirst(); + String oldValue = prod.category; + String newValue = "01234567890123456789"; + // 2 chars exceeds field max + prod.category = newValue; + db.update(prod); + + ProductAnnotationOnly newProd = db.from(p).where(p.productId).is(prod.productId).selectFirst(); + assertEquals(newValue.substring(0, 15), newProd.category); + + newProd.category = oldValue; + db.update(newProd); + } + + @Test + public void testColumnInheritanceAnnotation() { + ProductInheritedAnnotation table = new ProductInheritedAnnotation(); + List<ProductInheritedAnnotation> inserted = ProductInheritedAnnotation.getData(); + db.insertAll(inserted); + + List<ProductInheritedAnnotation> retrieved = db.from(table).select(); + + for (int j = 0; j < retrieved.size(); j++) { + ProductInheritedAnnotation i = inserted.get(j); + ProductInheritedAnnotation r = retrieved.get(j); + assertEquals(i.category, r.category); + assertEquals(i.mappedField, r.mappedField); + assertEquals(i.unitsInStock, r.unitsInStock); + assertEquals(i.unitPrice, r.unitPrice); + assertEquals(i.name(), r.name()); + assertEquals(i.id(), r.id()); + } + } + + @Test + public void testCreateTableIfRequiredAnnotation() { + // tests IQTable.createTableIfRequired=false + try { + db.insertAll(ProductNoCreateTable.getList()); + } catch (IciqlException e) { + assertEquals(IciqlException.CODE_OBJECT_NOT_FOUND, e.getIciqlCode()); + } + } + +} diff --git a/src/test/java/com/iciql/test/BooleanModelTest.java b/src/test/java/com/iciql/test/BooleanModelTest.java new file mode 100644 index 0000000..1e1630a --- /dev/null +++ b/src/test/java/com/iciql/test/BooleanModelTest.java @@ -0,0 +1,128 @@ +/*
+ * Copyright 2011 James Moger.
+ *
+ * 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.iciql.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.util.List;
+
+import org.junit.Test;
+
+import com.iciql.Db;
+import com.iciql.test.models.BooleanModel;
+import com.iciql.test.models.BooleanModel.BooleanAsIntModel;
+
+/**
+ * Tests interchangeable mapping of INT columns with Booleans and BOOL columns
+ * with Integers.
+ * <ul>
+ * <li>mapping a BIT/BOOLEAN column as an Integer
+ * <li>mapping a INT column as a Boolean.
+ * </ul>
+ */
+public class BooleanModelTest {
+
+ @Test
+ public void testBooleanColumn() {
+ Db db = IciqlSuite.openNewDb();
+ db.insertAll(BooleanModel.getList());
+ BooleanAsIntModel b = new BooleanAsIntModel();
+ List<BooleanAsIntModel> models = db.from(b).select();
+ int count = 0;
+ for (BooleanAsIntModel model : models) {
+ if ((model.id % 2) == 1) {
+ // assert that odd ids are true
+ assertTrue(model.mybool > 0);
+ } else {
+ // assert that even ids are false
+ assertTrue(model.mybool == 0);
+ }
+
+ // count true values
+ if (model.mybool > 0) {
+ count++;
+ }
+ }
+ assertEquals(2, count);
+
+ // invert boolean values and update
+ for (BooleanAsIntModel model : models) {
+ model.mybool = model.mybool > 0 ? 0 : 1;
+ }
+ db.updateAll(models);
+
+ // check even ids are true
+ models = db.from(b).select();
+ for (BooleanAsIntModel model : models) {
+ if ((model.id % 2) == 1) {
+ // assert that odd ids are false
+ assertTrue(model.mybool == 0);
+ } else {
+ // assert that even ids are true
+ assertTrue(model.mybool > 0);
+ }
+ }
+ db.close();
+ }
+
+ @Test
+ public void testIntColumn() {
+ Db db = IciqlSuite.openNewDb();
+ // insert INT column
+ db.insertAll(BooleanAsIntModel.getList());
+
+ // select all rows with INT column and map to Boolean
+ BooleanModel b = new BooleanModel();
+ List<BooleanModel> models = db.from(b).select();
+ int count = 0;
+ for (BooleanModel model : models) {
+ if ((model.id % 2) == 1) {
+ // assert that odd ids are true
+ assertTrue(model.mybool);
+ } else {
+ // assert that even ids are false
+ assertTrue(!model.mybool);
+ }
+
+ // count true values
+ if (model.mybool) {
+ count++;
+ }
+ }
+ assertEquals(2, count);
+
+ // invert boolean values and update
+ for (BooleanModel model : models) {
+ model.mybool = !model.mybool;
+ }
+ db.updateAll(models);
+
+ // check even ids are true
+ models = db.from(b).select();
+ for (BooleanModel model : models) {
+ if ((model.id % 2) == 1) {
+ // assert that odd ids are false
+ assertTrue(!model.mybool);
+ } else {
+ // assert that even ids are true
+ assertTrue(model.mybool);
+ }
+ }
+ db.close();
+ }
+}
diff --git a/src/test/java/com/iciql/test/ClobTest.java b/src/test/java/com/iciql/test/ClobTest.java new file mode 100644 index 0000000..49cee72 --- /dev/null +++ b/src/test/java/com/iciql/test/ClobTest.java @@ -0,0 +1,115 @@ +/* + * Copyright 2004-2011 H2 Group. + * Copyright 2011 James Moger. + * + * 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.iciql.test; + +import static com.iciql.Define.primaryKey; +import static com.iciql.Define.tableName; +import static org.junit.Assert.assertEquals; + +import java.text.MessageFormat; +import java.util.Arrays; +import java.util.List; + +import org.junit.Test; + +import com.iciql.Db; +import com.iciql.Iciql; + +/** + * Tests if converting a CLOB to a String works. + */ +public class ClobTest { + + @Test + public void testClob() throws Exception { + String create = "CREATE TABLE CLOB_TEST(ID INT PRIMARY KEY, WORDS {0})"; + Db db = IciqlSuite.openNewDb(); + db.executeUpdate(MessageFormat.format(create, "VARCHAR(255)")); + db.insertAll(StringRecord.getList()); + testSimpleUpdate(db, "VARCHAR fail"); + db.executeUpdate("DROP TABLE CLOB_TEST"); + db.close(); + + db = IciqlSuite.openNewDb(); + db.executeUpdate(MessageFormat.format(create, db.getDialect().convertSqlType("CLOB"))); + db.insertAll(StringRecord.getList()); + testSimpleUpdate(db, "CLOB fail because of single quote artifacts"); + db.executeUpdate("DROP TABLE CLOB_TEST"); + db.close(); + } + + private void testSimpleUpdate(Db db, String failureMsg) { + String newWords = "I changed the words"; + StringRecord r = new StringRecord(); + StringRecord originalRecord = db.from(r).where(r.id).is(2).selectFirst(); + String oldWords = originalRecord.words; + originalRecord.words = newWords; + db.update(originalRecord); + + StringRecord r2 = new StringRecord(); + StringRecord revisedRecord = db.from(r2).where(r2.id).is(2).selectFirst(); + assertEquals(failureMsg, newWords, revisedRecord.words); + + // undo update + originalRecord.words = oldWords; + db.update(originalRecord); + } + + /** + * A simple class used in this test. + */ + public static class StringRecord implements Iciql { + + public Integer id; + public String words; + + public StringRecord() { + // public constructor + } + + private StringRecord(int id, String words) { + this.id = id; + this.words = words; + } + + public void defineIQ() { + tableName("CLOB_TEST"); + primaryKey(id); + } + + private static StringRecord create(int id, String words) { + return new StringRecord(id, words); + } + + public static List<StringRecord> getList() { + StringRecord[] list = { + create(1, "Once upon a midnight dreary, while I pondered weak and weary,"), + create(2, "Over many a quaint and curious volume of forgotten lore,"), + create(3, "While I nodded, nearly napping, suddenly there came a tapping,"), + create(4, "As of some one gently rapping, rapping at my chamber door."), + create(5, "`'Tis some visitor,' I muttered, `tapping at my chamber door -"), + create(6, "Only this, and nothing more.'") }; + + return Arrays.asList(list); + } + + public String toString() { + return id + ": " + words; + } + } +} diff --git a/src/test/java/com/iciql/test/ConcurrencyTest.java b/src/test/java/com/iciql/test/ConcurrencyTest.java new file mode 100644 index 0000000..e248265 --- /dev/null +++ b/src/test/java/com/iciql/test/ConcurrencyTest.java @@ -0,0 +1,199 @@ +/* + * Copyright 2011 James Moger. + * + * 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.iciql.test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; + +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; + +import com.iciql.Db; +import com.iciql.IciqlException; +import com.iciql.Query; +import com.iciql.test.models.Product; +import com.iciql.util.Utils; + +/** + * Tests concurrency and alias instance sharing. + */ +public class ConcurrencyTest { + + private int numberOfTests = 800; + + @Before + public void setUp() { + Db db = IciqlSuite.openNewDb(); + db.insertAll(Product.getList()); + } + + @Test + public void testAliasSharing() throws Exception { + Db db = IciqlSuite.openCurrentDb(); + try { + // Single-threaded example of why aliases can NOT be shared. + Product p = new Product(); + Query<Product> query1 = db.from(p); + Query<Product> query2 = db.from(p); + + // if you could share alias instances both counts should be equal + long count1 = 0; + try { + count1 = query1.where(p.category).is("Beverages").selectCount(); + } catch (IciqlException e) { + assertEquals(IciqlException.CODE_UNMAPPED_FIELD, e.getIciqlCode()); + } + long count2 = query2.where(p.category).is("Beverages").selectCount(); + + // but they aren't + assertEquals(0, count1); + assertEquals(2, count2); + assertTrue(count1 != count2); + } finally { + db.close(); + } + } + + @Test + @Ignore + public void testConcurrencyFinal() throws Exception { + // Multi-threaded example of why aliases can NOT be shared. + // + // This test looks like it _could_ work and you may find that it _can_ + // work, but you should also find that it _will_ fail. + + List<Thread> threads = Utils.newArrayList(); + final AtomicInteger failures = new AtomicInteger(0); + final Product p = new Product(); + for (int i = 0; i < numberOfTests; i++) { + final int testNumber = i; + Thread t = new Thread(new Runnable() { + public void run() { + try { + int testCase = testNumber % 10; + test(testCase, p); + } catch (AssertionError e) { + failures.incrementAndGet(); + } catch (IciqlException e) { + failures.incrementAndGet(); + if (e.getIciqlCode() != IciqlException.CODE_UNMAPPED_FIELD) { + System.err.println("UNEXPECTED ERROR in testConcurrencyFinal()"); + e.printStackTrace(); + } + } + } + }, "ICIQL-" + i); + t.start(); + threads.add(t); + } + + // wait till all threads complete + for (Thread t : threads) { + t.join(); + } + + assertTrue("This should fail. Try running a few more times.", failures.get() > 0); + } + + @Test + @Ignore + public void testConcurrencyThreadLocal() throws Exception { + List<Thread> threads = Utils.newArrayList(); + final AtomicInteger failures = new AtomicInteger(0); + final ThreadLocal<Product> tl = Utils.newThreadLocal(Product.class); + for (int i = 0; i < numberOfTests; i++) { + final int testNumber = i; + Thread t = new Thread(new Runnable() { + public void run() { + try { + int testCase = testNumber % 10; + test(testCase, tl.get()); + } catch (AssertionError e) { + failures.incrementAndGet(); + } catch (IciqlException e) { + failures.incrementAndGet(); + if (e.getIciqlCode() != IciqlException.CODE_UNMAPPED_FIELD) { + System.err.println("UNEXPECTED ERROR in testConcurrencyThreadLocal()"); + e.printStackTrace(); + } + } + } + }, "ICIQL-" + i); + t.start(); + threads.add(t); + } + + // wait till all threads complete + for (Thread t : threads) { + t.join(); + } + + assertEquals("ThreadLocal should never fail!", 0, failures.get()); + } + + private void test(int testCase, Product p) throws AssertionError { + Db db = IciqlSuite.openCurrentDb(); + try { + List<Product> list; + switch (testCase) { + case 0: + list = db.from(p).where(p.productName).is("Chai").select(); + assertEquals(1, list.size()); + assertEquals("Chai", list.get(0).productName); + break; + case 1: + list = db.from(p).where(p.category).is("Condiments").select(); + assertEquals(5, list.size()); + break; + case 3: + list = db.from(p).where(p.productName).is("Aniseed Syrup").select(); + assertEquals(1, list.size()); + assertEquals("Aniseed Syrup", list.get(0).productName); + break; + case 4: + list = db.from(p).where(p.productName).like("Chef%").select(); + assertEquals(2, list.size()); + assertTrue(list.get(0).productName.startsWith("Chef")); + assertTrue(list.get(1).productName.startsWith("Chef")); + break; + case 6: + list = db.from(p).where(p.unitsInStock).exceeds(0).select(); + assertEquals(9, list.size()); + break; + case 7: + list = db.from(p).where(p.unitsInStock).is(0).select(); + assertEquals(1, list.size()); + assertEquals("Chef Anton's Gumbo Mix", list.get(0).productName); + break; + case 9: + list = db.from(p).where(p.productId).is(7).select(); + assertEquals(1, list.size()); + assertTrue(7 == list.get(0).productId); + break; + default: + list = db.from(p).select(); + assertEquals(10, list.size()); + } + } finally { + db.close(); + } + } +} diff --git a/src/test/java/com/iciql/test/DefaultValuesTest.java b/src/test/java/com/iciql/test/DefaultValuesTest.java new file mode 100644 index 0000000..1374379 --- /dev/null +++ b/src/test/java/com/iciql/test/DefaultValuesTest.java @@ -0,0 +1,61 @@ +/*
+ * Copyright 2011 James Moger.
+ *
+ * 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.iciql.test;
+
+import static org.junit.Assert.assertTrue;
+
+import java.util.List;
+
+import org.junit.Test;
+
+import com.iciql.Db;
+import com.iciql.DbInspector;
+import com.iciql.ValidationRemark;
+import com.iciql.test.models.DefaultValuesModel;
+
+/**
+ * Tests default object values.
+ */
+public class DefaultValuesTest {
+
+ @Test
+ public void testDefaultObjectValues() {
+ Db db = IciqlSuite.openNewDb();
+
+ // insert random model
+ DefaultValuesModel model = new DefaultValuesModel();
+ db.insert(model);
+
+ DefaultValuesModel v = new DefaultValuesModel();
+
+ // retrieve model and compare
+ DefaultValuesModel retrievedModel = db.from(v).selectFirst();
+ assertTrue(model.myInteger.equals(retrievedModel.myInteger));
+ assertTrue(model.myDate.equals(retrievedModel.myDate));
+ assertTrue(model.myEnumIdTree.equals(retrievedModel.myEnumIdTree));
+ assertTrue(model.myNameTree.equals(retrievedModel.myNameTree));
+ assertTrue(model.myOrdinalTree.equals(retrievedModel.myOrdinalTree));
+ assertTrue(retrievedModel.myNullTree == null);
+
+ DbInspector inspector = new DbInspector(db);
+ List<ValidationRemark> remarks = inspector.validateModel(model, false);
+ db.close();
+ for (ValidationRemark remark : remarks) {
+ System.out.println(remark.toString());
+ }
+ }
+}
diff --git a/src/test/java/com/iciql/test/EnumsTest.java b/src/test/java/com/iciql/test/EnumsTest.java new file mode 100644 index 0000000..d8a0589 --- /dev/null +++ b/src/test/java/com/iciql/test/EnumsTest.java @@ -0,0 +1,129 @@ +/*
+ * Copyright 2011 James Moger.
+ *
+ * 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.iciql.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.util.List;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.iciql.Db;
+import com.iciql.IciqlException;
+import com.iciql.test.models.EnumModels;
+import com.iciql.test.models.EnumModels.EnumIdModel;
+import com.iciql.test.models.EnumModels.EnumOrdinalModel;
+import com.iciql.test.models.EnumModels.EnumStringModel;
+import com.iciql.test.models.EnumModels.Tree;
+
+/**
+ * Tests enum support.
+ */
+public class EnumsTest {
+
+ private Db db;
+
+ @Before
+ public void setUp() {
+ db = IciqlSuite.openNewDb();
+ db.insertAll(EnumIdModel.createList());
+ db.insertAll(EnumOrdinalModel.createList());
+ db.insertAll(EnumStringModel.createList());
+ }
+
+ @After
+ public void tearDown() {
+ db.close();
+ }
+
+ @Test
+ public void testEnumQueries() {
+ testIntEnums(new EnumIdModel());
+ testIntEnums(new EnumOrdinalModel());
+ testStringEnums(new EnumStringModel());
+ }
+
+ private void testIntEnums(EnumModels e) {
+ // ensure all records inserted
+ long count = db.from(e).selectCount();
+ assertEquals(5, count);
+
+ // special case:
+ // value is first enum constant which is also the alias object.
+ // the first enum constant is used as the alias because we can not
+ // instantiate an enum reflectively.
+ EnumModels firstEnumValue = db.from(e).where(e.tree()).is(Tree.PINE).selectFirst();
+ assertEquals(Tree.PINE, firstEnumValue.tree());
+
+ EnumModels model = db.from(e).where(e.tree()).is(Tree.WALNUT).selectFirst();
+
+ assertEquals(400, model.id.intValue());
+ assertEquals(Tree.WALNUT, model.tree());
+
+ List<EnumModels> list = db.from(e).where(e.tree()).atLeast(Tree.BIRCH).select();
+ assertEquals(3, list.size());
+
+ // between is an int compare
+ list = db.from(e).where(e.tree()).between(Tree.BIRCH).and(Tree.WALNUT).select();
+ assertEquals(2, list.size());
+
+ }
+
+ private void testStringEnums(EnumModels e) {
+ // ensure all records inserted
+ long count = db.from(e).selectCount();
+ assertEquals(5, count);
+
+ // special case:
+ // value is first enum constant which is also the alias object.
+ // the first enum constant is used as the alias because we can not
+ // instantiate an enum reflectively.
+ EnumModels firstEnumValue = db.from(e).where(e.tree()).is(Tree.PINE).selectFirst();
+ assertEquals(Tree.PINE, firstEnumValue.tree());
+
+ EnumModels model = db.from(e).where(e.tree()).is(Tree.WALNUT).selectFirst();
+
+ assertEquals(400, model.id.intValue());
+ assertEquals(Tree.WALNUT, model.tree());
+
+ List<EnumModels> list = db.from(e).where(e.tree()).isNot(Tree.BIRCH).select();
+ assertEquals(count - 1, list.size());
+
+ // between is a string compare
+ list = db.from(e).where(e.tree()).between(Tree.MAPLE).and(Tree.PINE).select();
+ assertEquals(3, list.size());
+ }
+
+ @Test
+ public void testMultipleEnumInstances() {
+ BadEnums b = new BadEnums();
+ try {
+ db.from(b).where(b.tree1).is(Tree.BIRCH).and (b.tree2).is(Tree.MAPLE).getSQL();
+ assertTrue("Failed to detect multiple Tree fields?!", false);
+ } catch (IciqlException e) {
+ assertTrue(e.getMessage(), e.getMessage().startsWith("Can not explicitly reference Tree"));
+ }
+ }
+
+ public static class BadEnums {
+ Tree tree1 = Tree.BIRCH;
+ Tree tree2 = Tree.MAPLE;
+ }
+}
diff --git a/src/test/java/com/iciql/test/ForeignKeyTest.java b/src/test/java/com/iciql/test/ForeignKeyTest.java new file mode 100644 index 0000000..6b4a3e7 --- /dev/null +++ b/src/test/java/com/iciql/test/ForeignKeyTest.java @@ -0,0 +1,81 @@ +/*
+ * Copyright 2012 Frédéric Gaillard.
+ * Copyright 2012 James Moger.
+ *
+ * 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.iciql.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.iciql.Db;
+import com.iciql.IciqlException;
+import com.iciql.test.models.CategoryAnnotationOnly;
+import com.iciql.test.models.ProductAnnotationOnlyWithForeignKey;
+
+/**
+ * Tests of Foreign Keys.
+ */
+public class ForeignKeyTest {
+
+ /**
+ * This object represents a database (actually a connection to the
+ * database).
+ */
+
+ private Db db;
+
+ @Before
+ public void setUp() {
+ db = IciqlSuite.openNewDb();
+ db.insertAll(CategoryAnnotationOnly.getList());
+ db.insertAll(ProductAnnotationOnlyWithForeignKey.getList());
+ }
+
+ @After
+ public void tearDown() {
+ db.dropTable(ProductAnnotationOnlyWithForeignKey.class);
+ db.dropTable(CategoryAnnotationOnly.class);
+ db.close();
+ }
+
+ @Test
+ public void testForeignKeyWithOnDeleteCascade() {
+ ProductAnnotationOnlyWithForeignKey p = new ProductAnnotationOnlyWithForeignKey();
+ long count1 = db.from(p).selectCount();
+
+ // should remove 2 associated products
+ CategoryAnnotationOnly c = new CategoryAnnotationOnly();
+ db.from(c).where(c.categoryId).is(1L).delete();
+
+ long count2 = db.from(p).selectCount();
+
+ assertEquals(count1, count2 + 2L);
+ }
+
+ @Test
+ public void testForeignKeyDropReferenceTable() {
+ try {
+ db.dropTable(CategoryAnnotationOnly.class);
+ assertTrue("Should not be able to drop reference table!", false);
+ } catch (IciqlException e) {
+ assertEquals(e.getMessage(), IciqlException.CODE_CONSTRAINT_VIOLATION, e.getIciqlCode());
+ }
+ }
+
+}
diff --git a/src/test/java/com/iciql/test/IciqlSuite.java b/src/test/java/com/iciql/test/IciqlSuite.java new file mode 100644 index 0000000..a474404 --- /dev/null +++ b/src/test/java/com/iciql/test/IciqlSuite.java @@ -0,0 +1,614 @@ +/*
+ * Copyright 2011 James Moger.
+ * Copyright 2012 Frédéric Gaillard.
+ *
+ * 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.iciql.test;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.sql.SQLException;
+import java.text.DecimalFormat;
+import java.text.MessageFormat;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.dbcp.ConnectionFactory;
+import org.apache.commons.dbcp.DriverManagerConnectionFactory;
+import org.apache.commons.dbcp.PoolableConnectionFactory;
+import org.apache.commons.dbcp.PoolingDataSource;
+import org.apache.commons.pool.impl.GenericObjectPool;
+import org.hsqldb.persist.HsqlProperties;
+import org.junit.Assert;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Result;
+import org.junit.runner.RunWith;
+import org.junit.runner.notification.Failure;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+
+import com.beust.jcommander.JCommander;
+import com.beust.jcommander.Parameter;
+import com.beust.jcommander.ParameterException;
+import com.beust.jcommander.Parameters;
+import com.iciql.Constants;
+import com.iciql.Db;
+import com.iciql.test.models.BooleanModel;
+import com.iciql.test.models.CategoryAnnotationOnly;
+import com.iciql.test.models.ComplexObject;
+import com.iciql.test.models.Customer;
+import com.iciql.test.models.DefaultValuesModel;
+import com.iciql.test.models.EnumModels.EnumIdModel;
+import com.iciql.test.models.EnumModels.EnumOrdinalModel;
+import com.iciql.test.models.EnumModels.EnumStringModel;
+import com.iciql.test.models.MultipleBoolsModel;
+import com.iciql.test.models.Order;
+import com.iciql.test.models.PrimitivesModel;
+import com.iciql.test.models.Product;
+import com.iciql.test.models.ProductAnnotationOnly;
+import com.iciql.test.models.ProductAnnotationOnlyWithForeignKey;
+import com.iciql.test.models.ProductInheritedAnnotation;
+import com.iciql.test.models.ProductMixedAnnotation;
+import com.iciql.test.models.ProductView;
+import com.iciql.test.models.ProductViewFromQuery;
+import com.iciql.test.models.ProductViewInherited;
+import com.iciql.test.models.ProductViewInheritedComplex;
+import com.iciql.test.models.SupportedTypes;
+import com.iciql.util.IciqlLogger;
+import com.iciql.util.IciqlLogger.IciqlListener;
+import com.iciql.util.IciqlLogger.StatementType;
+import com.iciql.util.StringUtils;
+import com.iciql.util.Utils;
+
+/**
+ * JUnit 4 iciql test suite.
+ *
+ * By default this test suite will run against the H2 database. You can change
+ * this by switching the DEFAULT_TEST_DB value.
+ * <p>
+ * Alternatively, you can run this class an application which will run all tests
+ * for all tested database configurations.
+ * <p>
+ * NOTE: If you want to test against MySQL or PostgreSQL you must create an
+ * "iciql" database and allow user "sa" password "sa" complete control of that
+ * database.
+ *
+ */
+@RunWith(Suite.class)
+@SuiteClasses({ AliasMapTest.class, AnnotationsTest.class, BooleanModelTest.class, ClobTest.class,
+ ConcurrencyTest.class, EnumsTest.class, ModelsTest.class, PrimitivesTest.class,
+ RuntimeQueryTest.class, SamplesTest.class, UpdateTest.class, UpgradesTest.class, JoinTest.class,
+ UUIDTest.class, ViewsTest.class, ForeignKeyTest.class, TransactionTest.class })
+public class IciqlSuite {
+
+ private static final TestDb[] TEST_DBS = {
+ new TestDb("H2", true, true, "jdbc:h2:mem:iciql"),
+ new TestDb("H2", true, false, "jdbc:h2:file:testdbs/h2/iciql"),
+ new TestDb("H2", false, false, "jdbc:h2:tcp://localhost/"
+ + new File(System.getProperty("user.dir")).getAbsolutePath() + "/testdbs/h2tcp/iciql"),
+ new TestDb("HSQL", true, true, "jdbc:hsqldb:mem:iciql"),
+ new TestDb("HSQL", true, false, "jdbc:hsqldb:file:testdbs/hsql/iciql"),
+ new TestDb("HSQL", false, false, "jdbc:hsqldb:hsql://localhost/iciql"),
+ new TestDb("Derby", true, true, "jdbc:derby:memory:iciql;create=true"),
+ new TestDb("Derby", true, false, "jdbc:derby:directory:testdbs/derby/iciql;create=true"),
+ new TestDb("MySQL", false, false, "jdbc:mysql://localhost:7000/iciql", "sa", "sa"),
+ new TestDb("PostgreSQL", false, false, "jdbc:postgresql://localhost:5432/iciql", "sa", "sa") };
+
+ private static final TestDb DEFAULT_TEST_DB = TEST_DBS[0];
+
+ private static final PrintStream ERR = System.err;
+
+ private static PrintStream out = System.out;
+
+ private static Map<String, PoolableConnectionFactory> connectionFactories = Utils
+ .newSynchronizedHashMap();
+
+ private static Map<String, PoolingDataSource> dataSources = Utils.newSynchronizedHashMap();
+
+ public static void assertStartsWith(String value, String startsWith) {
+ Assert.assertTrue(MessageFormat.format("Expected \"{0}\", got: \"{1}\"", startsWith, value),
+ value.startsWith(startsWith));
+ }
+
+ public static void assertEqualsIgnoreCase(String expected, String actual) {
+ Assert.assertTrue(MessageFormat.format("Expected \"{0}\", got: \"{1}\"", expected, actual),
+ expected.equalsIgnoreCase(actual));
+ }
+
+ public static boolean equivalentTo(double expected, double actual) {
+ if (Double.compare(expected, actual) == 0) {
+ return true;
+ }
+ return Math.abs(expected - actual) <= 0.000001d;
+ }
+
+ /**
+ * Open a new Db object. All connections are cached and re-used to eliminate
+ * embedded database startup costs.
+ *
+ * @return a fresh Db object
+ */
+ public static Db openNewDb() {
+ String testUrl = System.getProperty("iciql.url", DEFAULT_TEST_DB.url);
+ String testUser = System.getProperty("iciql.user", DEFAULT_TEST_DB.username);
+ String testPassword = System.getProperty("iciql.password", DEFAULT_TEST_DB.password);
+
+ Db db = null;
+ PoolingDataSource dataSource = dataSources.get(testUrl);
+ if (dataSource == null) {
+ ConnectionFactory connectionFactory = new DriverManagerConnectionFactory(testUrl, testUser,
+ testPassword);
+ GenericObjectPool pool = new GenericObjectPool();
+ pool.setWhenExhaustedAction(GenericObjectPool.WHEN_EXHAUSTED_GROW);
+ PoolableConnectionFactory factory = new PoolableConnectionFactory(connectionFactory, pool, null,
+ null, false, true);
+ dataSource = new PoolingDataSource(pool);
+ dataSources.put(testUrl, dataSource);
+ connectionFactories.put(testUrl, factory);
+ }
+ db = Db.open(dataSource);
+
+ // drop views
+ db.dropView(ProductView.class);
+ db.dropView(ProductViewInherited.class);
+ db.dropView(ProductViewFromQuery.class);
+ db.dropView(ProductViewInheritedComplex.class);
+
+ // drop tables
+ db.dropTable(BooleanModel.class);
+ db.dropTable(ComplexObject.class);
+ db.dropTable(Customer.class);
+ db.dropTable(DefaultValuesModel.class);
+ db.dropTable(EnumIdModel.class);
+ db.dropTable(EnumOrdinalModel.class);
+ db.dropTable(EnumStringModel.class);
+ db.dropTable(Order.class);
+ db.dropTable(PrimitivesModel.class);
+ db.dropTable(Product.class);
+ db.dropTable(ProductAnnotationOnly.class);
+ db.dropTable(ProductInheritedAnnotation.class);
+ db.dropTable(ProductMixedAnnotation.class);
+ db.dropTable(SupportedTypes.class);
+ db.dropTable(JoinTest.UserId.class);
+ db.dropTable(JoinTest.UserNote.class);
+ db.dropTable(EnumsTest.BadEnums.class);
+ db.dropTable(MultipleBoolsModel.class);
+ db.dropTable(ProductAnnotationOnlyWithForeignKey.class);
+ db.dropTable(CategoryAnnotationOnly.class);
+
+ return db;
+ }
+
+ /**
+ * Open the current database.
+ *
+ * @return the current database
+ */
+ public static Db openCurrentDb() {
+ String testUrl = System.getProperty("iciql.url", DEFAULT_TEST_DB.url);
+ String testUser = System.getProperty("iciql.user", DEFAULT_TEST_DB.username);
+ String testPassword = System.getProperty("iciql.password", DEFAULT_TEST_DB.password);
+ return Db.open(testUrl, testUser, testPassword);
+ }
+
+ /**
+ * Returns the name of the underlying database engine for the Db object.
+ *
+ * @param db
+ * @return the database engine name
+ */
+ public static String getDatabaseEngineName(Db db) {
+ String database = "";
+ try {
+ database = db.getConnection().getMetaData().getDatabaseProductName();
+ } catch (SQLException s) {
+ }
+ return database;
+ }
+
+ /**
+ * Returns true if the underlying database engine is Derby.
+ *
+ * @param db
+ * @return true if underlying database engine is Derby
+ */
+ public static boolean isDerby(Db db) {
+ return IciqlSuite.getDatabaseEngineName(db).equals("Apache Derby");
+ }
+
+ /**
+ * Returns true if the underlying database engine is H2.
+ *
+ * @param db
+ * @return true if underlying database engine is H2
+ */
+ public static boolean isH2(Db db) {
+ return IciqlSuite.getDatabaseEngineName(db).equals("H2");
+ }
+
+ /**
+ * Returns true if the underlying database engine is MySQL.
+ *
+ * @param db
+ * @return true if underlying database engine is MySQL
+ */
+ public static boolean isMySQL(Db db) {
+ return IciqlSuite.getDatabaseEngineName(db).equals("MySQL");
+ }
+
+ /**
+ * Gets the default schema of the underlying database engine.
+ *
+ * @param db
+ * @return the default schema
+ */
+ public static String getDefaultSchema(Db db) {
+ if (isDerby(db)) {
+ // Derby sets default schema name to username
+ return "SA";
+ } else if (isMySQL(db)) {
+ // MySQL does not have schemas
+ return null;
+ }
+
+ return "PUBLIC";
+ }
+
+ /**
+ * Main entry point for the test suite. Executing this method will run the
+ * test suite on all registered databases.
+ *
+ * @param args
+ * @throws Exception
+ */
+ public static void main(String... args) throws Exception {
+ Params params = new Params();
+ JCommander jc = new JCommander(params);
+ try {
+ jc.parse(args);
+ } catch (ParameterException t) {
+ usage(jc, t);
+ }
+
+ // Replace System.out with a file
+ if (!StringUtils.isNullOrEmpty(params.dbPerformanceFile)) {
+ out = new PrintStream(params.dbPerformanceFile);
+ System.setErr(out);
+ }
+
+ deleteRecursively(new File("testdbs"));
+
+ // Start the HSQL and H2 servers in-process
+ org.hsqldb.Server hsql = startHSQL();
+ org.h2.tools.Server h2 = startH2();
+
+ // Statement logging
+ final FileWriter statementWriter;
+ if (StringUtils.isNullOrEmpty(params.sqlStatementsFile)) {
+ statementWriter = null;
+ } else {
+ statementWriter = new FileWriter(params.sqlStatementsFile);
+ }
+ IciqlListener statementListener = new IciqlListener() {
+ @Override
+ public void logIciql(StatementType type, String statement) {
+ if (statementWriter == null) {
+ return;
+ }
+ try {
+ statementWriter.append(statement);
+ statementWriter.append('\n');
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ };
+ IciqlLogger.registerListener(statementListener);
+
+ SuiteClasses suiteClasses = IciqlSuite.class.getAnnotation(SuiteClasses.class);
+ long quickestDatabase = Long.MAX_VALUE;
+ String dividerMajor = buildDivider('*', 79);
+ String dividerMinor = buildDivider('-', 79);
+
+ // Header
+ out.println(dividerMajor);
+ out.println(MessageFormat.format("{0} {1} ({2}) testing {3} database configurations", Constants.NAME,
+ Constants.VERSION, Constants.VERSION_DATE, TEST_DBS.length));
+ out.println(dividerMajor);
+ out.println();
+
+ showProperty("java.vendor");
+ showProperty("java.runtime.version");
+ showProperty("java.vm.name");
+ showProperty("os.name");
+ showProperty("os.version");
+ showProperty("os.arch");
+ showProperty("available processors", "" + Runtime.getRuntime().availableProcessors());
+ showProperty(
+ "available memory",
+ MessageFormat.format("{0,number,0.0} GB", ((double) Runtime.getRuntime().maxMemory())
+ / (1024 * 1024)));
+ out.println();
+
+ // Test a database
+ long lastCount = 0;
+ for (TestDb testDb : TEST_DBS) {
+ out.println(dividerMinor);
+ out.println("Testing " + testDb.describeDatabase());
+ out.println(" " + testDb.url);
+ out.println(dividerMinor);
+
+ // inject a database section delimiter in the statement log
+ if (statementWriter != null) {
+ statementWriter.append("\n\n");
+ statementWriter.append("# ").append(dividerMinor).append('\n');
+ statementWriter.append("# ").append("Testing " + testDb.describeDatabase()).append('\n');
+ statementWriter.append("# ").append(dividerMinor).append('\n');
+ statementWriter.append("\n\n");
+ }
+
+ if (testDb.getVersion().equals("OFFLINE")) {
+ // Database not available
+ out.println("Skipping. Could not find " + testDb.url);
+ out.println();
+ } else {
+ // Setup system properties
+ System.setProperty("iciql.url", testDb.url);
+ System.setProperty("iciql.user", testDb.username);
+ System.setProperty("iciql.password", testDb.password);
+
+ // Test database
+ Result result = JUnitCore.runClasses(suiteClasses.value());
+
+ // Report results
+ testDb.runtime = result.getRunTime();
+ if (testDb.runtime < quickestDatabase) {
+ quickestDatabase = testDb.runtime;
+ }
+ testDb.statements = IciqlLogger.getTotalCount() - lastCount;
+ // reset total count for next database
+ lastCount = IciqlLogger.getTotalCount();
+
+ out.println(MessageFormat.format(
+ "{0} tests ({1} failures, {2} ignores) {3} statements in {4,number,0.000} secs",
+ result.getRunCount(), result.getFailureCount(), result.getIgnoreCount(),
+ testDb.statements, result.getRunTime() / 1000f));
+
+ if (result.getFailureCount() == 0) {
+ out.println();
+ out.println(" 100% successful test suite run.");
+ out.println();
+ } else {
+ for (Failure failure : result.getFailures()) {
+ out.println(MessageFormat.format("\n + {0}\n {1}", failure.getTestHeader(),
+ failure.getMessage()));
+ }
+ out.println();
+ }
+ }
+ }
+
+ // Display runtime results sorted by performance leader
+ out.println();
+ out.println(dividerMajor);
+ out.println(MessageFormat.format("{0} {1} ({2}) test suite performance results", Constants.NAME,
+ Constants.VERSION, Constants.VERSION_DATE));
+ out.println(dividerMajor);
+ List<TestDb> dbs = Arrays.asList(TEST_DBS);
+ Collections.sort(dbs);
+
+ out.println(MessageFormat.format("{0} {1} {2} {3} {4}", StringUtils.pad("Name", 11, " ", true),
+ StringUtils.pad("Type", 5, " ", true), StringUtils.pad("Version", 23, " ", true),
+ StringUtils.pad("Stats/Sec", 10, " ", true), "Runtime"));
+ out.println(dividerMinor);
+ for (TestDb testDb : dbs) {
+ DecimalFormat df = new DecimalFormat("0.0");
+ out.println(MessageFormat.format("{0} {1} {2} {3} {4} {5}s ({6,number,0.0}x)",
+ StringUtils.pad(testDb.name, 11, " ", true), testDb.isEmbedded ? "E" : "T",
+ testDb.isMemory ? "M" : "F", StringUtils.pad(testDb.getVersion(), 21, " ", true),
+ StringUtils.pad("" + testDb.getStatementRate(), 10, " ", false),
+ StringUtils.pad(df.format(testDb.getRuntime()), 8, " ", false), ((double) testDb.runtime)
+ / quickestDatabase));
+ }
+ out.println(dividerMinor);
+ out.println(" E = embedded connection");
+ out.println(" T = tcp/ip connection");
+ out.println(" M = memory database");
+ out.println(" F = file/persistent database");
+
+ // cleanup
+ for (PoolableConnectionFactory factory : connectionFactories.values()) {
+ factory.getPool().close();
+ }
+ IciqlLogger.unregisterListener(statementListener);
+ out.close();
+ System.setErr(ERR);
+ if (statementWriter != null) {
+ statementWriter.close();
+ }
+ hsql.stop();
+ h2.stop();
+ System.exit(0);
+ }
+
+ private static void showProperty(String name) {
+ showProperty(name, System.getProperty(name));
+ }
+
+ private static void showProperty(String name, String value) {
+ out.print(' ');
+ out.print(StringUtils.pad(name, 25, " ", true));
+ out.println(value);
+ }
+
+ private static void usage(JCommander jc, ParameterException t) {
+ System.out.println(Constants.NAME + " test suite v" + Constants.VERSION);
+ System.out.println();
+ if (t != null) {
+ System.out.println(t.getMessage());
+ System.out.println();
+ }
+ if (jc != null) {
+ jc.usage();
+ }
+ System.exit(0);
+ }
+
+ private static String buildDivider(char c, int length) {
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < length; i++) {
+ sb.append(c);
+ }
+ return sb.toString();
+ }
+
+ private static void deleteRecursively(File f) {
+ if (f.isDirectory()) {
+ for (File file : f.listFiles()) {
+ if (file.isDirectory()) {
+ deleteRecursively(file);
+ }
+ file.delete();
+ }
+ }
+ f.delete();
+ }
+
+ /**
+ * Start an HSQL tcp server.
+ *
+ * @return an HSQL server instance
+ * @throws Exception
+ */
+ private static org.hsqldb.Server startHSQL() throws Exception {
+ HsqlProperties p = new HsqlProperties();
+ String db = new File(System.getProperty("user.dir")).getAbsolutePath() + "/testdbs/hsqltcp/iciql";
+ p.setProperty("server.database.0", "file:" + db);
+ p.setProperty("server.dbname.0", "iciql");
+ // set up the rest of properties
+
+ // alternative to the above is
+ org.hsqldb.Server server = new org.hsqldb.Server();
+ server.setProperties(p);
+ server.setLogWriter(null);
+ server.setErrWriter(null);
+ server.start();
+ return server;
+ }
+
+ /**
+ * Start the H2 tcp server.
+ *
+ * @return an H2 server instance
+ * @throws Exception
+ */
+ private static org.h2.tools.Server startH2() throws Exception {
+ org.h2.tools.Server server = org.h2.tools.Server.createTcpServer();
+ server.start();
+ return server;
+ }
+
+ /**
+ * Represents a test database url.
+ */
+ private static class TestDb implements Comparable<TestDb> {
+ final String name;
+ boolean isEmbedded;
+ boolean isMemory;
+ final String url;
+ final String username;
+ final String password;
+ String version;
+ long runtime;
+ long statements;
+
+ TestDb(String name, boolean isEmbedded, boolean isMemory, String url) {
+ this(name, isEmbedded, isMemory, url, "sa", "");
+ }
+
+ TestDb(String name, boolean isEmbedded, boolean isMemory, String url, String username, String password) {
+ this.name = name;
+ this.isEmbedded = isEmbedded;
+ this.isMemory = isMemory;
+ this.url = url;
+ this.username = username;
+ this.password = password;
+ }
+
+ double getRuntime() {
+ return runtime / 1000d;
+ }
+
+ int getStatementRate() {
+ return Double.valueOf(((double) statements) / (runtime / 1000d)).intValue();
+ }
+
+ String describeDatabase() {
+ StringBuilder sb = new StringBuilder(name);
+ sb.append(" ");
+ sb.append(getVersion());
+ return sb.toString();
+ }
+
+ String getVersion() {
+ if (version == null) {
+ try {
+ Db db = Db.open(url, username, password);
+ version = db.getConnection().getMetaData().getDatabaseProductVersion();
+ db.close();
+ return version;
+ } catch (Throwable t) {
+ version = "OFFLINE";
+ }
+ }
+ return version;
+ }
+
+ @Override
+ public int compareTo(TestDb o) {
+ if (runtime == 0) {
+ return 1;
+ }
+ if (o.runtime == 0) {
+ return -1;
+ }
+ int r1 = getStatementRate();
+ int r2 = o.getStatementRate();
+ if (r1 == r2) {
+ return 0;
+ }
+ if (r1 < r2) {
+ return 1;
+ }
+ return -1;
+ }
+ }
+
+ /**
+ * Command-line parameters for TestSuite.
+ */
+ @Parameters(separators = " ")
+ private static class Params {
+
+ @Parameter(names = { "--dbFile" }, description = "Database performance results text file", required = false)
+ public String dbPerformanceFile;
+
+ @Parameter(names = { "--sqlFile" }, description = "SQL statements log file", required = false)
+ public String sqlStatementsFile;
+ }
+}
\ No newline at end of file diff --git a/src/test/java/com/iciql/test/JoinTest.java b/src/test/java/com/iciql/test/JoinTest.java new file mode 100644 index 0000000..0e5e39d --- /dev/null +++ b/src/test/java/com/iciql/test/JoinTest.java @@ -0,0 +1,173 @@ +/* + * Copyright 2011 James Moger. + * + * 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.iciql.test; + +import static org.junit.Assert.assertEquals; + +import java.util.Arrays; +import java.util.List; + +import org.junit.After; +import org.junit.Assume; +import org.junit.Before; +import org.junit.Test; + +import com.iciql.Db; +import com.iciql.Iciql.IQColumn; +import com.iciql.Iciql.IQTable; +import com.iciql.QueryWhere; + +/** + * Tests of Joins. + */ +public class JoinTest { + + Db db; + + @Before + public void setup() { + db = IciqlSuite.openNewDb(); + + db.insertAll(UserId.getList()); + db.insertAll(UserNote.getList()); + } + + @After + public void tearDown() { + db.close(); + } + + @Test + public void testPrimitiveJoin() throws Exception { + final UserId u = new UserId(); + final UserNote n = new UserNote(); + + List<UserNote> notes = db.from(u).innerJoin(n).on(u.id).is(n.userId).where(u.id).is(2) + .select(new UserNote() { + { + userId = n.userId; + noteId = n.noteId; + text = n.text; + } + }); + assertEquals(3, notes.size()); + } + + @Test + public void testJoin() throws Exception { + final UserId u = new UserId(); + final UserNote n = new UserNote(); + + // this query returns 1 UserId if the user has a note + // it's purpose is to confirm fluency/type-safety on a very simple + // join case where the main table is filtered/reduced by hits in a + // related table + + List<UserId> users = db.from(u).innerJoin(n).on(u.id).is(n.userId).where(u.id).is(2).selectDistinct(); + + assertEquals(1, users.size()); + assertEquals(2, users.get(0).id); + } + + @Test + public void testLeftJoin() throws Exception { + final UserId u = new UserId(); + final UserNote n = new UserNote(); + + List<UserId> notes = db.from(u).leftJoin(n).on(u.id).is(n.userId).where(u.id).is(4).select(); + assertEquals(1, notes.size()); + assertEquals(4, notes.get(0).id); + } + + @Test + public void testSubQuery() throws Exception { + final UserId u = new UserId(); + final UserNote n = new UserNote(); + + QueryWhere<UserId> q = db.from(u).where(u.id).in(db.from(n).where(n.userId).exceeds(0).subQuery(n.userId)); + List<UserId> notes = q.select(); + assertEquals(3, notes.size()); + + // do not test MySQL on this statement because the databases + if (IciqlSuite.isMySQL(db)) { + assertEquals("SELECT * FROM UserId WHERE `id` in (SELECT `userId` FROM UserNote WHERE `userId` > 0 )", q.toSQL()); + } else { + assertEquals("SELECT * FROM UserId WHERE id in (SELECT userId FROM UserNote WHERE userId > 0 )", q.toSQL()); + } + } + + @IQTable + public static class UserId { + + @IQColumn(primaryKey = true) + public int id; + + @IQColumn(length = 10) + public String name; + + public UserId() { + // public constructor + } + + public UserId(int id, String name) { + this.id = id; + this.name = name; + } + + public String toString() { + return name + " (" + id + ")"; + } + + public static List<UserId> getList() { + UserId[] list = { new UserId(1, "Tom"), new UserId(2, "Dick"), new UserId(3, "Harry"), new UserId(4, "Jack") }; + return Arrays.asList(list); + } + } + + @IQTable + public static class UserNote { + + @IQColumn(autoIncrement = true, primaryKey = true) + public int noteId; + + @IQColumn + public int userId; + + @IQColumn(length = 10) + public String text; + + public UserNote() { + // public constructor + } + + public UserNote(int userId, String text) { + this.userId = userId; + this.text = text; + } + + public String toString() { + return text; + } + + public static List<UserNote> getList() { + UserNote[] list = { new UserNote(1, "A"), new UserNote(2, "B"), new UserNote(3, "C"), + new UserNote(1, "D"), new UserNote(2, "E"), new UserNote(3, "F"), new UserNote(1, "G"), + new UserNote(2, "H"), new UserNote(3, "I"), }; + return Arrays.asList(list); + } + } +} diff --git a/src/test/java/com/iciql/test/ModelsTest.java b/src/test/java/com/iciql/test/ModelsTest.java new file mode 100644 index 0000000..c5ba27a --- /dev/null +++ b/src/test/java/com/iciql/test/ModelsTest.java @@ -0,0 +1,145 @@ +/* + * Copyright 2004-2011 H2 Group. + * Copyright 2011 James Moger. + * + * 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.iciql.test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static com.iciql.test.IciqlSuite.assertEqualsIgnoreCase; + +import java.sql.SQLException; +import java.text.MessageFormat; +import java.util.List; + +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ErrorCollector; + +import com.iciql.Db; +import com.iciql.DbInspector; +import com.iciql.ValidationRemark; +import com.iciql.test.models.Product; +import com.iciql.test.models.ProductAnnotationOnly; +import com.iciql.test.models.ProductMixedAnnotation; +import com.iciql.test.models.SupportedTypes; +import com.iciql.util.StringUtils; + +/** + * Test that the mapping between classes and tables is done correctly. + */ +public class ModelsTest { + + /* + * The ErrorCollector Rule allows execution of a test to continue after the + * first problem is found and report them all at once + */ + @Rule + public ErrorCollector errorCollector = new ErrorCollector(); + + private Db db; + + @Before + public void setUp() { + db = IciqlSuite.openNewDb(); + db.insertAll(Product.getList()); + db.insertAll(ProductAnnotationOnly.getList()); + db.insertAll(ProductMixedAnnotation.getList()); + } + + @After + public void tearDown() { + db.close(); + } + + @Test + public void testValidateModels() { + String schemaName = IciqlSuite.getDefaultSchema(db); + DbInspector inspector = new DbInspector(db); + validateModel(inspector, schemaName, new ProductAnnotationOnly(), 2); + validateModel(inspector, schemaName, new ProductMixedAnnotation(), 4); + } + + private void validateModel(DbInspector inspector, String schemaName, Object o, int expected) { + List<ValidationRemark> remarks = inspector.validateModel(o, false); + assertTrue("validation remarks are null for " + o.getClass().getName(), remarks != null); + StringBuilder sb = new StringBuilder(); + sb.append("validation remarks for " + o.getClass().getName()); + sb.append('\n'); + for (ValidationRemark remark : remarks) { + sb.append(remark.toString()); + sb.append('\n'); + if (remark.isError()) { + errorCollector.addError(new SQLException(remark.toString())); + } + } + + if (StringUtils.isNullOrEmpty(schemaName)) { + // no schema expected + assertEquals(sb.toString(), expected - 1, remarks.size()); + } else { + assertEquals(sb.toString(), expected, remarks.size()); + assertEqualsIgnoreCase(MessageFormat.format("@IQSchema(\"{0}\")", schemaName), + remarks.get(0).message); + } + } + + @Test + public void testSupportedTypes() { + List<SupportedTypes> original = SupportedTypes.createList(); + db.insertAll(original); + List<SupportedTypes> retrieved = db.from(SupportedTypes.SAMPLE).select(); + assertEquals(original.size(), retrieved.size()); + for (int i = 0; i < original.size(); i++) { + SupportedTypes o = original.get(i); + SupportedTypes r = retrieved.get(i); + assertTrue(o.equivalentTo(r)); + } + } + + @Test + public void testModelGeneration() { + List<SupportedTypes> original = SupportedTypes.createList(); + db.insertAll(original); + DbInspector inspector = new DbInspector(db); + List<String> models = inspector.generateModel(null, "SupportedTypes", "com.iciql.test.models", true, + true); + assertEquals(1, models.size()); + // a poor test, but a start + String dbName = IciqlSuite.getDatabaseEngineName(db); + if (dbName.equals("H2")) { + assertEquals(1587, models.get(0).length()); + } else if (dbName.startsWith("HSQL")) { + // HSQL uses Double instead of Float + assertEquals(1591, models.get(0).length()); + } else if (dbName.equals("Apache Derby")) { + // Derby uses java.sql.Timestamp not java.util.Date + // Derby uses username as schema name + assertEquals(1601, models.get(0).length()); + } else if (dbName.equals("PostgreSQL")) { + assertEquals(1643, models.get(0).length()); + } else if (dbName.equals("MySQL")) { + // MySQL uses timestamp default values like + // 0000-00-00 00:00:00 and CURRENT_TIMESTAMP + assertEquals(1673, models.get(0).length()); + } else { + // unknown database + assertEquals(0, models.get(0).length()); + } + } +} diff --git a/src/test/java/com/iciql/test/PrimitivesTest.java b/src/test/java/com/iciql/test/PrimitivesTest.java new file mode 100644 index 0000000..3d3811e --- /dev/null +++ b/src/test/java/com/iciql/test/PrimitivesTest.java @@ -0,0 +1,102 @@ +/*
+ * Copyright 2011 James Moger.
+ *
+ * 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.iciql.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Collections;
+import java.util.List;
+
+import org.junit.Test;
+
+import com.iciql.Db;
+import com.iciql.IciqlException;
+import com.iciql.test.models.MultipleBoolsModel;
+import com.iciql.test.models.PrimitivesModel;
+
+/**
+ * Tests primitives with autoboxing within the framework.
+ */
+public class PrimitivesTest {
+
+ @Test
+ public void testPrimitives() {
+ Db db = IciqlSuite.openNewDb();
+
+ // insert random models in reverse order
+ List<PrimitivesModel> models = PrimitivesModel.getList();
+ PrimitivesModel model = models.get(0);
+ Collections.reverse(models);
+ // insert them in reverse order
+ db.insertAll(models);
+
+ PrimitivesModel p = new PrimitivesModel();
+
+ // retrieve model and compare
+ PrimitivesModel retrievedModel = db.from(p).orderBy(p.myLong).selectFirst();
+ assertTrue(model.equivalentTo(retrievedModel));
+
+ retrievedModel = db.from(p).where("mylong = ? and myinteger = ?", model.myLong, model.myInteger)
+ .selectFirst();
+ assertTrue(model.equivalentTo(retrievedModel));
+
+ // retrieve with conditions and compare
+ retrievedModel = db.from(p).where(p.myLong).is(model.myLong).and(p.myInteger).is(model.myInteger)
+ .selectFirst();
+ assertTrue(model.equivalentTo(retrievedModel));
+
+ // set myInteger & myDouble
+ db.from(p).set(p.myInteger).to(10).set(p.myDouble).to(3.0d).where(p.myLong).is(model.myLong).update();
+ retrievedModel = db.from(p).orderBy(p.myLong).selectFirst();
+
+ assertEquals(10, retrievedModel.myInteger);
+ assertEquals(3d, retrievedModel.myDouble, 0.001d);
+
+ // increment my double by pi
+ db.from(p).increment(p.myDouble).by(3.14d).update();
+ retrievedModel = db.from(p).orderBy(p.myLong).selectFirst();
+ assertEquals(6.14d, retrievedModel.myDouble, 0.001d);
+
+ // test order by
+ List<PrimitivesModel> list = db.from(p).orderBy(p.myLong).select();
+ assertEquals(models.size(), list.size());
+ assertEquals("[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]", list.toString());
+
+ // test model update
+ retrievedModel.myInteger = 1337;
+ assertEquals(1, db.update(retrievedModel));
+ assertEquals(1, db.delete(retrievedModel));
+
+ db.close();
+ }
+
+ @Test
+ public void testMultipleBooleans() {
+ Db db = IciqlSuite.openNewDb();
+ db.insertAll(MultipleBoolsModel.getList());
+
+ MultipleBoolsModel m = new MultipleBoolsModel();
+ try {
+ db.from(m).where(m.a).is(true).select();
+ assertTrue(false);
+ } catch (IciqlException e) {
+ assertTrue(true);
+ }
+ db.close();
+ }
+}
diff --git a/src/test/java/com/iciql/test/RuntimeQueryTest.java b/src/test/java/com/iciql/test/RuntimeQueryTest.java new file mode 100644 index 0000000..c23527f --- /dev/null +++ b/src/test/java/com/iciql/test/RuntimeQueryTest.java @@ -0,0 +1,199 @@ +/*
+ * Copyright 2011 James Moger.
+ *
+ * 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.iciql.test;
+
+import static org.junit.Assert.assertEquals;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.text.MessageFormat;
+import java.text.SimpleDateFormat;
+import java.util.List;
+
+import org.junit.Assume;
+import org.junit.Test;
+
+import com.iciql.Db;
+import com.iciql.QueryWhere;
+import com.iciql.test.models.EnumModels.Tree;
+import com.iciql.test.models.Product;
+import com.iciql.test.models.StaticQueries;
+import com.iciql.util.JdbcUtils;
+import com.iciql.util.Utils;
+
+/**
+ * Tests the runtime dynamic query function.
+ */
+public class RuntimeQueryTest {
+
+ @Test
+ public void testParameters() {
+ Db db = IciqlSuite.openNewDb();
+
+ // do not test non-H2 databases because dialects will get in the way
+ // e.g. column quoting, etc
+ Assume.assumeTrue(IciqlSuite.isH2(db));
+
+ Product p = new Product();
+ String q1 = db.from(p).where(p.unitsInStock).isParameter().and(p.productName).likeParameter().orderBy(p.productId).toSQL();
+ String q2 = db.from(p).where(p.unitsInStock).lessThan(100).and(p.productName).like("test").or(p.productName).likeParameter().orderBy(p.productId).toSQL();
+
+ StaticQueries.StaticModel1 m1 = new StaticQueries.StaticModel1();
+ String q3 = db.from(m1).where(m1.myTree).is(Tree.MAPLE).and(m1.myTree).isParameter().toSQL();
+
+ StaticQueries.StaticModel2 m2 = new StaticQueries.StaticModel2();
+ String q4 = db.from(m2).where(m2.myTree).is(Tree.MAPLE).and(m2.myTree).isParameter().toSQL();
+
+ StaticQueries.StaticModel3 m3 = new StaticQueries.StaticModel3();
+ String q5 = db.from(m3).where(m3.myTree).is(Tree.MAPLE).and(m3.myTree).isParameter().toSQL();
+
+ long now = System.currentTimeMillis();
+ java.sql.Date aDate = new java.sql.Date(now);
+ java.sql.Time aTime = new java.sql.Time(now);
+ java.sql.Timestamp aTimestamp = new java.sql.Timestamp(now);
+
+ String q6 = db.from(m1).where(m1.myDate).is(aDate).and(m1.myDate).isParameter().toSQL();
+ String q7 = db.from(m1).where(m1.myTime).is(aTime).and(m1.myTime).isParameter().toSQL();
+ String q8 = db.from(m1).where(m1.myTimestamp).is(aTimestamp).and(m1.myTimestamp).isParameter().toSQL();
+
+ db.close();
+ assertEquals("SELECT * FROM Product WHERE unitsInStock = ? AND productName LIKE ? ORDER BY productId", q1);
+ assertEquals("SELECT * FROM Product WHERE unitsInStock < 100 AND productName LIKE 'test' OR productName LIKE ? ORDER BY productId", q2);
+
+ assertEquals("SELECT * FROM StaticQueryTest1 WHERE myTree = 'MAPLE' AND myTree = ?", q3);
+ assertEquals("SELECT * FROM StaticQueryTest2 WHERE myTree = 50 AND myTree = ?", q4);
+ assertEquals("SELECT * FROM StaticQueryTest3 WHERE myTree = 4 AND myTree = ?", q5);
+
+ java.util.Date refDate = new java.util.Date(now);
+ assertEquals("SELECT * FROM StaticQueryTest1 WHERE myDate = '" + new SimpleDateFormat("yyyy-MM-dd").format(refDate) + "' AND myDate = ?", q6);
+ assertEquals("SELECT * FROM StaticQueryTest1 WHERE myTime = '" + new SimpleDateFormat("HH:mm:ss").format(refDate) + "' AND myTime = ?", q7);
+ assertEquals("SELECT * FROM StaticQueryTest1 WHERE myTimestamp = '" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(refDate) + "' AND myTimestamp = ?", q8);
+ }
+
+ @Test
+ public void testRuntimeSet() {
+ Db db = IciqlSuite.openNewDb();
+
+ // do not test non-H2 databases because dialects will get in the way
+ // e.g. column quoting, etc
+ Assume.assumeTrue(IciqlSuite.isH2(db));
+
+ StaticQueries.StaticModel1 m = new StaticQueries.StaticModel1();
+ String q = db.from(m).set(m.myTimestamp).toParameter().where(m.id).isParameter().toSQL();
+ db.close();
+
+ assertEquals("UPDATE StaticQueryTest1 SET myTimestamp = ? WHERE id = ?", q);
+ }
+
+ @Test
+ public void testRuntimeSelectWildcards() {
+ Db db = IciqlSuite.openNewDb();
+
+ // do not test non-H2 databases because dialects will get in the way
+ // e.g. column quoting, etc
+ Assume.assumeTrue(IciqlSuite.isH2(db));
+
+ StaticQueries.StaticModel1 m1 = new StaticQueries.StaticModel1();
+ StaticQueries.StaticModel2 m2 = new StaticQueries.StaticModel2();
+ StaticQueries.StaticModel2 m3 = new StaticQueries.StaticModel2();
+
+ int t0 = Utils.AS_COUNTER.get() + 1;
+ int t1 = t0 + 1;
+
+ QueryWhere<?> where = db.from(m1).innerJoin(m2).on(m1.id).is(m2.id).where(m2.myTree).is(Tree.MAPLE);
+ String q1 = where.toSQL(false);
+ String q2 = where.toSQL(true);
+ String q3 = where.toSQL(false, m1);
+ String q4 = where.toSQL(true, m1);
+ String q5 = where.toSQL(false, m2);
+ String q6 = where.toSQL(true, m2);
+
+ // test unused alias
+ String q7 = where.toSQL(true, m3);
+
+ db.close();
+
+ assertEquals(MessageFormat.format("SELECT * FROM StaticQueryTest1 AS T{0,number,0} INNER JOIN StaticQueryTest2 AS T{1,number,0} ON T{0,number,0}.id = T{1,number,0}.id WHERE T{1,number,0}.myTree = 50", t0, t1), q1);
+ assertEquals(MessageFormat.format("SELECT DISTINCT * FROM StaticQueryTest1 AS T{0,number,0} INNER JOIN StaticQueryTest2 AS T{1,number,0} ON T{0,number,0}.id = T{1,number,0}.id WHERE T{1,number,0}.myTree = 50", t0, t1), q2);
+
+ assertEquals(MessageFormat.format("SELECT T{0,number,0}.* FROM StaticQueryTest1 AS T{0,number,0} INNER JOIN StaticQueryTest2 AS T{1,number,0} ON T{0,number,0}.id = T{1,number,0}.id WHERE T{1,number,0}.myTree = 50", t0, t1), q3);
+ assertEquals(MessageFormat.format("SELECT DISTINCT T{0,number,0}.* FROM StaticQueryTest1 AS T{0,number,0} INNER JOIN StaticQueryTest2 AS T{1,number,0} ON T{0,number,0}.id = T{1,number,0}.id WHERE T{1,number,0}.myTree = 50", t0, t1), q4);
+
+ assertEquals(MessageFormat.format("SELECT T{1,number,0}.* FROM StaticQueryTest1 AS T{0,number,0} INNER JOIN StaticQueryTest2 AS T{1,number,0} ON T{0,number,0}.id = T{1,number,0}.id WHERE T{1,number,0}.myTree = 50", t0, t1), q5);
+ assertEquals(MessageFormat.format("SELECT DISTINCT T{1,number,0}.* FROM StaticQueryTest1 AS T{0,number,0} INNER JOIN StaticQueryTest2 AS T{1,number,0} ON T{0,number,0}.id = T{1,number,0}.id WHERE T{1,number,0}.myTree = 50", t0, t1), q6);
+
+ assertEquals(MessageFormat.format("SELECT DISTINCT * FROM StaticQueryTest1 AS T{0,number,0} INNER JOIN StaticQueryTest2 AS T{1,number,0} ON T{0,number,0}.id = T{1,number,0}.id WHERE T{1,number,0}.myTree = 50", t0, t1), q7);
+ }
+
+ @Test
+ public void testRuntimeQuery() {
+ Db db = IciqlSuite.openNewDb();
+ db.insertAll(Product.getList());
+
+ Product p = new Product();
+ List<Product> products = db.from(p).where("unitsInStock=?", 120).orderBy(p.productId).select();
+ assertEquals(1, products.size());
+
+ products = db.from(p).where("unitsInStock=? and productName like ? order by productId", 0, "Chef%")
+ .select();
+ assertEquals(1, products.size());
+
+ db.close();
+ }
+
+ @Test
+ public void testExecuteQuery() throws SQLException {
+ Db db = IciqlSuite.openNewDb();
+ db.insertAll(Product.getList());
+
+ // test plain statement
+ List<Product> products = db.executeQuery(Product.class,
+ "select * from product where unitsInStock=120");
+ assertEquals(1, products.size());
+ assertEquals("Condiments", products.get(0).category);
+
+ // test prepared statement
+ products = db.executeQuery(Product.class, "select * from product where unitsInStock=?", 120);
+ assertEquals(1, products.size());
+ assertEquals("Condiments", products.get(0).category);
+
+ db.close();
+ }
+
+ @Test
+ public void testBuildObjects() throws SQLException {
+ Db db = IciqlSuite.openNewDb();
+ db.insertAll(Product.getList());
+
+ // test plain statement
+ ResultSet rs = db.executeQuery("select * from product where unitsInStock=120");
+ List<Product> products = db.buildObjects(Product.class, rs);
+ JdbcUtils.closeSilently(rs, true);
+
+ assertEquals(1, products.size());
+ assertEquals("Condiments", products.get(0).category);
+
+ // test prepared statement
+ rs = db.executeQuery("select * from product where unitsInStock=?", 120);
+ products = db.buildObjects(Product.class, rs);
+ JdbcUtils.closeSilently(rs, true);
+
+ assertEquals(1, products.size());
+ assertEquals("Condiments", products.get(0).category);
+
+ db.close();
+ }
+}
diff --git a/src/test/java/com/iciql/test/SamplesTest.java b/src/test/java/com/iciql/test/SamplesTest.java new file mode 100644 index 0000000..49a64f5 --- /dev/null +++ b/src/test/java/com/iciql/test/SamplesTest.java @@ -0,0 +1,442 @@ +/*
+ * Copyright 2004-2011 H2 Group.
+ * Copyright 2011 James Moger.
+ *
+ * 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.iciql.test;
+
+import static com.iciql.Function.count;
+import static com.iciql.Function.isNull;
+import static com.iciql.Function.length;
+import static com.iciql.Function.max;
+import static com.iciql.Function.min;
+import static com.iciql.Function.not;
+import static com.iciql.Function.sum;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.math.BigDecimal;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.iciql.Db;
+import com.iciql.Filter;
+import com.iciql.Iciql.IQColumn;
+import com.iciql.test.models.ComplexObject;
+import com.iciql.test.models.Customer;
+import com.iciql.test.models.Order;
+import com.iciql.test.models.Product;
+import com.iciql.test.models.SupportedTypes;
+
+/**
+ * This is the implementation of the 101 LINQ Samples as described in
+ * http://msdn2.microsoft.com/en-us/vcsharp/aa336760.aspx
+ */
+public class SamplesTest {
+
+ /**
+ * This object represents a database (actually a connection to the
+ * database).
+ */
+
+ Db db;
+
+ @Before
+ public void setUp() {
+ db = IciqlSuite.openNewDb();
+ db.insertAll(Product.getList());
+ db.insertAll(Customer.getList());
+ db.insertAll(Order.getList());
+ db.insertAll(ComplexObject.getList());
+ }
+
+ @After
+ public void tearDown() {
+ db.close();
+ }
+
+ /**
+ * A simple test table. The columns are in a different order than in the
+ * database.
+ */
+ public static class TestReverse {
+ public String name;
+ public Integer id;
+ }
+
+ @Test
+ public void testReverseColumns() {
+ db.executeUpdate("create table TestReverse(id int, name varchar(10), additional varchar(10))");
+ TestReverse t = new TestReverse();
+ t.id = 10;
+ t.name = "Hello";
+ db.insert(t);
+ TestReverse check = db.from(new TestReverse()).selectFirst();
+ assertEquals(t.name, check.name);
+ assertEquals(t.id, check.id);
+ db.executeUpdate("DROP TABLE testreverse");
+ }
+
+ @Test
+ public void testWhereSimple2() {
+
+ // var soldOutProducts =
+ // from p in products
+ // where p.UnitsInStock == 0
+ // select p;
+
+ Product p = new Product();
+ List<Product> soldOutProducts = db.from(p).where(p.unitsInStock).is(0).orderBy(p.productId).select();
+ List<Product> soldOutProducts2 = db.from(p).where(p.unitsInStock).is(0).orderBy(p.productId).select(p);
+
+ assertEquals("[Chef Anton's Gumbo Mix: 0]", soldOutProducts.toString());
+ assertEquals(soldOutProducts.toString(), soldOutProducts2.toString());
+ }
+
+ @Test
+ public void testWhereSimple3() {
+
+ // var expensiveInStockProducts =
+ // from p in products
+ // where p.UnitsInStock > 0
+ // && p.UnitPrice > 3.00M
+ // select p;
+
+ Product p = new Product();
+ List<Product> expensiveInStockProducts = db.from(p).where(p.unitsInStock).exceeds(0).and(p.unitPrice)
+ .exceeds(30.0).orderBy(p.productId).select();
+
+ assertEquals("[Northwoods Cranberry Sauce: 6, Mishi Kobe Niku: 29, Ikura: 31]",
+ expensiveInStockProducts.toString());
+ }
+
+ @Test
+ public void testWhereSimple4() {
+
+ // var waCustomers =
+ // from c in customers
+ // where c.Region == "WA"
+ // select c;
+
+ Customer c = new Customer();
+ List<Customer> waCustomers = db.from(c).where(c.region).is("WA").select();
+
+ assertEquals("[ALFKI, ANATR]", waCustomers.toString());
+ }
+
+ @Test
+ public void testSelectSimple2() {
+
+ // var productNames =
+ // from p in products
+ // select p.ProductName;
+
+ Product p = new Product();
+ List<String> productNames = db.from(p).orderBy(p.productId).select(p.productName);
+
+ List<Product> products = Product.getList();
+ for (int i = 0; i < products.size(); i++) {
+ assertEquals(products.get(i).productName, productNames.get(i));
+ }
+ }
+
+ /**
+ * A result set class containing the product name and price.
+ */
+ public static class ProductPrice {
+ public String productName;
+ public String category;
+ @IQColumn(name = "unitPrice")
+ public Double price;
+ }
+
+ @Test
+ public void testAnonymousTypes3() {
+
+ // var productInfos =
+ // from p in products
+ // select new {
+ // p.ProductName,
+ // p.Category,
+ // Price = p.UnitPrice
+ // };
+
+ final Product p = new Product();
+ List<ProductPrice> productInfos = db.from(p).orderBy(p.productId).select(new ProductPrice() {
+ {
+ productName = p.productName;
+ category = p.category;
+ price = p.unitPrice;
+ }
+ });
+
+ List<Product> products = Product.getList();
+ assertEquals(products.size(), productInfos.size());
+ for (int i = 0; i < products.size(); i++) {
+ ProductPrice pr = productInfos.get(i);
+ Product p2 = products.get(i);
+ assertEquals(p2.productName, pr.productName);
+ assertEquals(p2.category, pr.category);
+ assertEquals(p2.unitPrice, pr.price);
+ }
+ }
+
+ /**
+ * A result set class containing customer data and the order total.
+ */
+ public static class CustOrder {
+ public String customerId;
+ public Integer orderId;
+ public BigDecimal total;
+
+ public String toString() {
+ return customerId + ":" + orderId + ":" + total;
+ }
+ }
+
+ @Test
+ public void testSelectManyCompoundFrom2() {
+
+ // var orders =
+ // from c in customers,
+ // o in c.Orders
+ // where o.Total < 500.00M
+ // select new {
+ // c.CustomerID,
+ // o.OrderID,
+ // o.Total
+ // };
+
+ final Customer c = new Customer();
+ final Order o = new Order();
+ List<CustOrder> orders = db.from(c).innerJoin(o).on(c.customerId).is(o.customerId).where(o.total)
+ .lessThan(new BigDecimal("100.00")).orderBy(c.customerId).select(new CustOrder() {
+ {
+ customerId = c.customerId;
+ orderId = o.orderId;
+ total = o.total;
+ }
+ });
+
+ assertEquals("[ANATR:10308:88.80]", orders.toString());
+ }
+
+ @Test
+ public void testIsNull() {
+ Product p = new Product();
+ String sql = db.from(p).whereTrue(isNull(p.productName)).getSQL();
+ assertEquals("SELECT * FROM Product WHERE (" + db.getDialect().prepareColumnName("productName")
+ + " IS NULL)", sql);
+ }
+
+ @Test
+ public void testDelete() {
+ Product p = new Product();
+ int deleted = db.from(p).where(p.productName).like("A%").delete();
+ assertEquals(1, deleted);
+ deleted = db.from(p).delete();
+ assertEquals(9, deleted);
+ db.insertAll(Product.getList());
+ db.deleteAll(Product.getList());
+ assertEquals(0, db.from(p).selectCount());
+ db.insertAll(Product.getList());
+ }
+
+ @Test
+ public void testOrAndNot() {
+ Product p = new Product();
+ String sql = db.from(p).whereTrue(not(isNull(p.productName))).getSQL();
+ String productName = db.getDialect().prepareColumnName("productName");
+ assertEquals("SELECT * FROM Product WHERE (NOT " + productName + " IS NULL)", sql);
+ sql = db.from(p).whereTrue(not(isNull(p.productName))).getSQL();
+ assertEquals("SELECT * FROM Product WHERE (NOT " + productName + " IS NULL)", sql);
+ sql = db.from(p).whereTrue(db.test(p.productId).is(1)).getSQL();
+ String productId = db.getDialect().prepareColumnName("productId");
+ assertEquals("SELECT * FROM Product WHERE ((" + productId + " = ?))", sql);
+ }
+
+ @Test
+ public void testLength() {
+ Product p = new Product();
+ List<Integer> lengths = db.from(p).where(length(p.productName)).lessThan(10)
+ .selectDistinct(length(p.productName));
+ // Formerly used orderBy(1) here, but that is not portable across DBs
+ Collections.sort(lengths);
+ assertEquals("[4, 5]", lengths.toString());
+ }
+
+ @Test
+ public void testSum() {
+ Product p = new Product();
+ Number sum = db.from(p).selectFirst(sum(p.unitsInStock));
+ assertEquals(323, sum.intValue());
+ Double sumPrice = db.from(p).selectFirst(sum(p.unitPrice));
+ assertEquals(313.35, sumPrice.doubleValue(), 0.001);
+ }
+
+ @Test
+ public void testMinMax() {
+ Product p = new Product();
+ Integer min = db.from(p).selectFirst(min(p.unitsInStock));
+ assertEquals(0, min.intValue());
+ String minName = db.from(p).selectFirst(min(p.productName));
+ assertEquals("Aniseed Syrup", minName);
+ Double max = db.from(p).selectFirst(max(p.unitPrice));
+ assertEquals(97.0, max.doubleValue(), 0.001);
+ }
+
+ @Test
+ public void testLike() {
+ Product p = new Product();
+ List<Product> aList = db.from(p).where(p.productName).like("Cha%").orderBy(p.productName).select();
+ assertEquals("[Chai: 39, Chang: 17]", aList.toString());
+ }
+
+ @Test
+ public void testCount() {
+ long count = db.from(new Product()).selectCount();
+ assertEquals(10, count);
+ }
+
+ @Test
+ public void testComplexObject() {
+ ComplexObject co = new ComplexObject();
+ String sql = db.from(co).where(co.id).is(1).and(co.amount).is(1L).and(co.birthday)
+ .lessThan(new java.util.Date()).and(co.created)
+ .lessThan(java.sql.Timestamp.valueOf("2005-05-05 05:05:05")).and(co.name).is("hello")
+ .and(co.time).lessThan(java.sql.Time.valueOf("23:23:23")).and(co.value)
+ .is(new BigDecimal("1")).getSQL();
+
+ StringBuilder sb = new StringBuilder();
+ sb.append("SELECT * FROM ComplexObject WHERE ");
+ sb.append(db.getDialect().prepareColumnName("id"));
+ sb.append(" = ? AND ");
+ sb.append(db.getDialect().prepareColumnName("amount"));
+ sb.append(" = ? AND ");
+ sb.append(db.getDialect().prepareColumnName("birthday"));
+ sb.append(" < ? AND ");
+ sb.append(db.getDialect().prepareColumnName("created"));
+ sb.append(" < ? AND ");
+ sb.append(db.getDialect().prepareColumnName("name"));
+ sb.append(" = ? AND ");
+ sb.append(db.getDialect().prepareColumnName("time"));
+ sb.append(" < ? AND ");
+ sb.append(db.getDialect().prepareColumnName("value"));
+ sb.append(" = ?");
+ assertEquals(sb.toString(), sql);
+
+ long count = db.from(co).where(co.id).is(1).and(co.amount).is(1L).and(co.birthday)
+ .lessThan(new java.util.Date()).and(co.created)
+ .lessThan(java.sql.Timestamp.valueOf("2005-05-05 05:05:05")).and(co.name).is("hello")
+ .and(co.time).lessThan(java.sql.Time.valueOf("23:23:23")).and(co.value)
+ .is(new BigDecimal("1")).selectCount();
+ assertEquals(1, count);
+ }
+
+ @Test
+ public void testComplexObject2() {
+ testComplexObject2(1, "hello");
+ }
+
+ private void testComplexObject2(final int x, final String name) {
+ final ComplexObject co = new ComplexObject();
+
+ String sql = db.from(co).where(new Filter() {
+ public boolean where() {
+ return co.id == x && co.name.equals(name) && co.name.equals("hello");
+ }
+ }).getSQL();
+ StringBuilder sb = new StringBuilder();
+ sb.append("SELECT * FROM ComplexObject WHERE ");
+ sb.append(db.getDialect().prepareColumnName("id"));
+ sb.append("=? AND ?=");
+ sb.append(db.getDialect().prepareColumnName("name"));
+ sb.append(" AND 'hello'=");
+ sb.append(db.getDialect().prepareColumnName("name"));
+ assertEquals(sb.toString(), sql);
+
+ long count = db.from(co).where(new Filter() {
+ public boolean where() {
+ return co.id == x && co.name.equals(name) && co.name.equals("hello");
+ }
+ }).selectCount();
+
+ assertEquals(1, count);
+ }
+
+ @Test
+ public void testLimitOffset() {
+ Set<Integer> ids = new HashSet<Integer>();
+ Product p = new Product();
+ for (int i = 0; i < 5; i++) {
+ List<Product> products = db.from(p).limit(2).offset(2 * i).select();
+ assertTrue(products.size() == 2);
+ for (Product prod : products) {
+ assertTrue("Failed to add product id. Duplicate?", ids.add(prod.productId));
+ }
+ }
+ }
+
+ @Test
+ public void testKeyRetrieval() {
+ List<SupportedTypes> list = SupportedTypes.createList();
+ List<Long> keys = db.insertAllAndGetKeys(list);
+ Set<Long> uniqueKeys = new HashSet<Long>();
+ for (Long l : keys) {
+ assertTrue("Failed to add key. Duplicate?", uniqueKeys.add(l));
+ }
+ }
+
+ /**
+ * A result set class containing product groups.
+ */
+ public static class ProductGroup {
+ public String category;
+ public Long productCount;
+
+ public String toString() {
+ return category + ":" + productCount;
+ }
+ }
+
+ @Test
+ public void testGroup() {
+
+ // var orderGroups =
+ // from p in products
+ // group p by p.Category into g
+ // select new {
+ // Category = g.Key,
+ // Products = g
+ // };
+
+ final Product p = new Product();
+ List<ProductGroup> list = db.from(p).groupBy(p.category).orderBy(p.category)
+ .select(new ProductGroup() {
+ {
+ category = p.category;
+ productCount = count();
+ }
+ });
+ assertEquals("[Beverages:2, Condiments:5, Meat/Poultry:1, Produce:1, Seafood:1]", list.toString());
+ }
+
+}
diff --git a/src/test/java/com/iciql/test/TransactionTest.java b/src/test/java/com/iciql/test/TransactionTest.java new file mode 100644 index 0000000..026366e --- /dev/null +++ b/src/test/java/com/iciql/test/TransactionTest.java @@ -0,0 +1,119 @@ +/*
+ * Copyright 2012 Frédéric Gaillard.
+ *
+ * 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.iciql.test;
+
+import static org.junit.Assert.assertEquals;
+
+import java.sql.SQLException;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.iciql.Db;
+import com.iciql.IciqlException;
+import com.iciql.test.models.CategoryAnnotationOnly;
+import com.iciql.test.models.ProductAnnotationOnlyWithForeignKey;
+
+/**
+ * Tests of transactions.
+ */
+public class TransactionTest {
+
+ /**
+ * This object represents a database (actually a connection to the
+ * database).
+ */
+
+ private Db db;
+
+ @Before
+ public void setUp() {
+ db = IciqlSuite.openNewDb();
+
+ // tables creation
+ db.from(new CategoryAnnotationOnly());
+ db.from(new ProductAnnotationOnlyWithForeignKey());
+
+ startTransactionMode();
+ }
+
+ @After
+ public void tearDown() {
+
+ endTransactionMode();
+
+ db.dropTable(ProductAnnotationOnlyWithForeignKey.class);
+ db.dropTable(CategoryAnnotationOnly.class);
+ db.close();
+ }
+
+ @Test
+ public void testTransaction() {
+
+ // insert in 2 tables inside a transaction
+
+ // insertAll don't use save point in this transaction
+ db.insertAll(CategoryAnnotationOnly.getList());
+ db.insertAll(ProductAnnotationOnlyWithForeignKey.getList());
+
+ // don't commit changes
+ try {
+ db.getConnection().rollback();
+ } catch (SQLException e) {
+ throw new IciqlException(e, "Can't rollback");
+ }
+
+ ProductAnnotationOnlyWithForeignKey p = new ProductAnnotationOnlyWithForeignKey();
+ long count1 = db.from(p).selectCount();
+
+ CategoryAnnotationOnly c = new CategoryAnnotationOnly();
+ long count2 = db.from(c).selectCount();
+
+ // verify changes aren't committed
+ assertEquals(count1, 0L);
+ assertEquals(count2, 0L);
+ }
+
+ /**
+ * Helper to set transaction mode
+ */
+ private void startTransactionMode() {
+ db.setSkipCreate(true);
+ db.setAutoSavePoint(false);
+
+ try {
+ db.getConnection().setAutoCommit(false);
+ } catch (SQLException e) {
+ throw new IciqlException(e, "Could not change auto-commit mode");
+ }
+ }
+
+ /**
+ * Helper to return to initial mode
+ */
+ private void endTransactionMode() {
+ try {
+ db.getConnection().setAutoCommit(true);
+ } catch (SQLException e) {
+ throw new IciqlException(e, "Could not change auto-commit mode");
+ }
+ // returns to initial states
+ db.setSkipCreate(false);
+ db.setAutoSavePoint(true);
+ }
+
+}
diff --git a/src/test/java/com/iciql/test/UUIDTest.java b/src/test/java/com/iciql/test/UUIDTest.java new file mode 100644 index 0000000..bb09c9f --- /dev/null +++ b/src/test/java/com/iciql/test/UUIDTest.java @@ -0,0 +1,115 @@ +/* + * Copyright 2011 James Moger. + * + * 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.iciql.test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +import org.junit.After; +import org.junit.Assume; +import org.junit.Before; +import org.junit.Test; + +import com.iciql.Db; +import com.iciql.Iciql.IQColumn; +import com.iciql.Iciql.IQTable; + +/** + * Tests of UUID type. + * <p> + * H2 only. + */ +public class UUIDTest { + + Db db; + + @Before + public void setup() { + db = IciqlSuite.openNewDb(); + } + + @After + public void tearDown() { + db.close(); + } + + @Test + public void testUUIDs() throws Exception { + // do not test non-H2 databases + Assume.assumeTrue(IciqlSuite.isH2(db)); + + List<UUIDRecord> originals = UUIDRecord.getList(); + db.insertAll(originals); + UUIDRecord u = new UUIDRecord(); + List<UUIDRecord> retrieved = db.from(u).orderBy(u.id).select(); + assertEquals(originals.size(), retrieved.size()); + for (int i = 0; i < originals.size(); i++) { + UUIDRecord a = originals.get(i); + UUIDRecord b = retrieved.get(i); + assertTrue(a.equivalentTo(b)); + } + + UUIDRecord second = db.from(u).where(u.uuid).is(originals.get(1).uuid).selectFirst(); + assertTrue(originals.get(1).equivalentTo(second)); + db.dropTable(UUIDRecord.class); + } + + /** + * A simple class used in this test. + */ + @IQTable(name = "UUID_TEST") + public static class UUIDRecord { + + @IQColumn(primaryKey = true) + public Integer id; + + @IQColumn() + public UUID uuid; + + public UUIDRecord() { + // public constructor + } + + private UUIDRecord(int id) { + this.id = id; + this.uuid = UUID.randomUUID(); + } + + public boolean equivalentTo(UUIDRecord b) { + boolean same = true; + same &= id == b.id; + same &= uuid.equals(b.uuid); + return same; + } + + public String toString() { + return id + ": " + uuid; + } + + public static List<UUIDRecord> getList() { + List<UUIDRecord> list = new ArrayList<UUIDRecord>(); + for (int i = 0; i < 10; i++) { + list.add(new UUIDRecord(i + 1)); + } + return list; + } + } +} diff --git a/src/test/java/com/iciql/test/UpdateTest.java b/src/test/java/com/iciql/test/UpdateTest.java new file mode 100644 index 0000000..717c23a --- /dev/null +++ b/src/test/java/com/iciql/test/UpdateTest.java @@ -0,0 +1,160 @@ +/* + * Copyright 2004-2011 H2 Group. + * Copyright 2011 James Moger. + * + * 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.iciql.test; + +import static java.sql.Date.valueOf; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.iciql.Db; +import com.iciql.test.models.Customer; +import com.iciql.test.models.Order; +import com.iciql.test.models.Product; + +/** + * Tests the Db.update() function. + * + * @author dmoebius at scoop dash gmbh dot de + */ +public class UpdateTest { + + private Db db; + + @Before + public void setUp() throws Exception { + db = IciqlSuite.openNewDb(); + db.insertAll(Product.getList()); + db.insertAll(Customer.getList()); + db.insertAll(Order.getList()); + } + + @After + public void tearDown() { + db.close(); + } + + @Test + public void testSimpleUpdate() { + Product p = new Product(); + Product pChang = db.from(p).where(p.productName).is("Chang").selectFirst(); + // update unitPrice from 19.0 to 19.5 + pChang.unitPrice = 19.5; + // update unitsInStock from 17 to 16 + pChang.unitsInStock = 16; + db.update(pChang); + + Product p2 = new Product(); + Product pChang2 = db.from(p2).where(p2.productName).is("Chang").selectFirst(); + assertEquals(19.5, pChang2.unitPrice.doubleValue(), 0.001); + assertEquals(16, pChang2.unitsInStock.intValue()); + + // undo update + pChang.unitPrice = 19.0; + pChang.unitsInStock = 17; + db.update(pChang); + } + + @Test + public void testSimpleUpdateWithCombinedPrimaryKey() { + Order o = new Order(); + Order ourOrder = db.from(o).where(o.orderDate).is(valueOf("2007-01-02")).selectFirst(); + ourOrder.orderDate = valueOf("2007-01-03"); + db.update(ourOrder); + + Order ourUpdatedOrder = db.from(o).where(o.orderDate).is(valueOf("2007-01-03")).selectFirst(); + assertTrue("updated order not found", ourUpdatedOrder != null); + + // undo update + ourOrder.orderDate = valueOf("2007-01-02"); + db.update(ourOrder); + } + + @Test + public void testSimpleMerge() { + Product p = new Product(); + Product pChang = db.from(p).where(p.productName).is("Chang").selectFirst(); + // update unitPrice from 19.0 to 19.5 + pChang.unitPrice = 19.5; + // update unitsInStock from 17 to 16 + pChang.unitsInStock = 16; + db.merge(pChang); + + Product p2 = new Product(); + Product pChang2 = db.from(p2).where(p2.productName).is("Chang").selectFirst(); + assertEquals(19.5, pChang2.unitPrice, 0.001); + assertEquals(16, pChang2.unitsInStock.intValue()); + + // undo update + pChang.unitPrice = 19.0; + pChang.unitsInStock = 17; + db.merge(pChang); + } + + @Test + public void testSimpleMergeWithCombinedPrimaryKey() { + Order o = new Order(); + Order ourOrder = db.from(o).where(o.orderDate).is(valueOf("2007-01-02")).selectFirst(); + ourOrder.orderDate = valueOf("2007-01-03"); + db.merge(ourOrder); + + Order ourUpdatedOrder = db.from(o).where(o.orderDate).is(valueOf("2007-01-03")).selectFirst(); + assertTrue("updated order not found", ourUpdatedOrder != null); + + // undo update + ourOrder.orderDate = valueOf("2007-01-02"); + db.merge(ourOrder); + } + + @Test + public void testSetColumns() { + Product p = new Product(); + Product original = db.from(p).where(p.productId).is(1).selectFirst(); + + // update string and double columns + db.from(p).set(p.productName).to("updated").increment(p.unitPrice).by(3.14).increment(p.unitsInStock) + .by(2).where(p.productId).is(1).update(); + + // confirm the data was properly updated + Product revised = db.from(p).where(p.productId).is(1).selectFirst(); + assertEquals("updated", revised.productName); + assertEquals(original.unitPrice + 3.14, revised.unitPrice, 0.001); + assertEquals(original.unitsInStock + 2, revised.unitsInStock.intValue()); + + // restore the data + db.from(p).set(p.productName).to(original.productName).set(p.unitPrice).to(original.unitPrice) + .increment(p.unitsInStock).by(-2).where(p.productId).is(1).update(); + + // confirm the data was properly restored + Product restored = db.from(p).where(p.productId).is(1).selectFirst(); + assertEquals(original.productName, restored.productName); + assertEquals(original.unitPrice, restored.unitPrice); + assertEquals(original.unitsInStock, restored.unitsInStock); + + double unitPriceOld = db.from(p).where(p.productId).is(1).selectFirst().unitPrice; + // double the unit price + db.from(p).increment(p.unitPrice).by(p.unitPrice).where(p.productId).is(1).update(); + double unitPriceNew = db.from(p).where(p.productId).is(1).selectFirst().unitPrice; + assertEquals(unitPriceOld * 2, unitPriceNew, 0.001); + + } + +} diff --git a/src/test/java/com/iciql/test/UpgradesTest.java b/src/test/java/com/iciql/test/UpgradesTest.java new file mode 100644 index 0000000..7de691f --- /dev/null +++ b/src/test/java/com/iciql/test/UpgradesTest.java @@ -0,0 +1,180 @@ +/*
+ * Copyright 2011 James Moger.
+ *
+ * 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.iciql.test;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.junit.Test;
+
+import com.iciql.Db;
+import com.iciql.DbUpgrader;
+import com.iciql.Iciql.IQVersion;
+import com.iciql.test.models.Product;
+import com.iciql.test.models.SupportedTypes;
+import com.iciql.test.models.SupportedTypes.SupportedTypes2;
+
+/**
+ * Tests the database and table upgrade functions.
+ *
+ */
+public class UpgradesTest {
+
+ @Test
+ public void testDatabaseUpgrade() {
+ Db db = IciqlSuite.openNewDb();
+
+ List<Product> products = Product.getList();
+
+ // set the v1 upgrader and insert a record.
+ // this will trigger the upgrade.
+ V1DbUpgrader v1 = new V1DbUpgrader();
+ db.setDbUpgrader(v1);
+ db.insert(products.get(0));
+
+ // confirm that upgrade occurred
+ assertEquals(0, v1.oldVersion.get());
+ assertEquals(1, v1.newVersion.get());
+
+ // open a second connection to the database
+ // and then apply the v2 upgrade.
+ // For H2 its important to keep the first connection
+ // alive so that the database is not destroyed.
+ Db db2 = IciqlSuite.openCurrentDb();
+
+ // set the v2 upgrader and insert a record.
+ // this will trigger the upgrade.
+ V2DbUpgrader v2 = new V2DbUpgrader();
+ db2.setDbUpgrader(v2);
+ db2.insert(products.get(1));
+
+ // confirm that upgrade occurred
+ assertEquals(1, v2.oldVersion.get());
+ assertEquals(2, v2.newVersion.get());
+
+ db.executeUpdate("DROP TABLE iq_versions");
+ db.close();
+ db2.close();
+ }
+
+ @Test
+ public void testDatabaseInheritedUpgrade() {
+ Db db = IciqlSuite.openNewDb();
+
+ List<Product> products = Product.getList();
+
+ // set the v1 upgrader and insert a record.
+ // this will trigger the upgrade.
+ V1DbUpgrader v1 = new V1DbUpgrader();
+ db.setDbUpgrader(v1);
+ db.insert(products.get(0));
+
+ // confirm that upgrade occurred
+ assertEquals(0, v1.oldVersion.get());
+ assertEquals(1, v1.newVersion.get());
+
+ // open a second connection to the database
+ // and then apply the v2 upgrade.
+ // For H2 its important to keep the first connection
+ // alive so that the database is not destroyed.
+ Db db2 = IciqlSuite.openCurrentDb();
+
+ // set the v2 upgrader and insert a record.
+ // this will trigger the upgrade.
+ V2DbUpgraderImpl v2 = new V2DbUpgraderImpl();
+ db2.setDbUpgrader(v2);
+ db2.insert(products.get(1));
+
+ // confirm that upgrade occurred
+ assertEquals(1, v2.oldVersion.get());
+ assertEquals(2, v2.newVersion.get());
+
+ db.executeUpdate("DROP TABLE iq_versions");
+ db.close();
+ db2.close();
+ }
+
+ @Test
+ public void testTableUpgrade() {
+ Db db = IciqlSuite.openNewDb();
+
+ // insert first, this will create version record automatically
+ List<SupportedTypes> original = SupportedTypes.createList();
+ db.insertAll(original);
+
+ // reset the dbUpgrader (clears the update check cache)
+ V2DbUpgrader dbUpgrader = new V2DbUpgrader();
+ db.setDbUpgrader(dbUpgrader);
+
+ SupportedTypes2 s2 = new SupportedTypes2();
+
+ List<SupportedTypes2> types = db.from(s2).select();
+ assertEquals(10, types.size());
+ assertEquals(1, dbUpgrader.oldVersion.get());
+ assertEquals(2, dbUpgrader.newVersion.get());
+ db.executeUpdate("DROP TABLE iq_versions");
+ db.close();
+ }
+
+ /**
+ * A sample database upgrader class.
+ */
+ class BaseDbUpgrader implements DbUpgrader {
+ final AtomicInteger oldVersion = new AtomicInteger(0);
+ final AtomicInteger newVersion = new AtomicInteger(0);
+
+ public boolean upgradeTable(Db db, String schema, String table, int fromVersion, int toVersion) {
+ // just claims success on upgrade request
+ oldVersion.set(fromVersion);
+ newVersion.set(toVersion);
+ return true;
+ }
+
+ public boolean upgradeDatabase(Db db, int fromVersion, int toVersion) {
+ // just claims success on upgrade request
+ oldVersion.set(fromVersion);
+ newVersion.set(toVersion);
+ return true;
+ }
+ }
+
+ /**
+ * A sample V1 database upgrader class.
+ */
+ @IQVersion(1)
+ class V1DbUpgrader extends BaseDbUpgrader {
+ }
+
+ /**
+ * A sample V2 database upgrader class.
+ */
+ @IQVersion(2)
+ class V2DbUpgrader extends BaseDbUpgrader {
+ }
+
+
+ /**
+ * A sample V2 database upgrader class which inherits its
+ * version from the parent class.
+ */
+ @IQVersion()
+ class V2DbUpgraderImpl extends V2DbUpgrader {
+ }
+
+}
diff --git a/src/test/java/com/iciql/test/ViewsTest.java b/src/test/java/com/iciql/test/ViewsTest.java new file mode 100644 index 0000000..be2e085 --- /dev/null +++ b/src/test/java/com/iciql/test/ViewsTest.java @@ -0,0 +1,114 @@ +/* + * Copyright 2012 James Moger. + * + * 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.iciql.test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.List; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.iciql.Db; +import com.iciql.test.models.ProductAnnotationOnly; +import com.iciql.test.models.ProductView; +import com.iciql.test.models.ProductViewFromQuery; +import com.iciql.test.models.ProductViewInherited; +import com.iciql.test.models.ProductViewInheritedComplex; +import com.mysql.jdbc.StringUtils; + +/** + * Test annotation processing. + */ +public class ViewsTest { + + /** + * This object represents a database (actually a connection to the + * database). + */ + + private Db db; + + @Before + public void setUp() { + db = IciqlSuite.openNewDb(); + db.insertAll(ProductAnnotationOnly.getList()); + } + + @After + public void tearDown() { + db.close(); + } + + @Test + public void testProductView() { + ProductView view = new ProductView(); + List<ProductView> products = db.from(view).select(); + assertEquals(5, products.size()); + for (int i = 0; i < products.size(); i++) { + assertEquals(3 + i, products.get(i).productId.intValue()); + } + } + + @Test + public void testProductViewInherited() { + ProductViewInherited view = new ProductViewInherited(); + List<ProductViewInherited> products = db.from(view).select(); + assertEquals(5, products.size()); + for (int i = 0; i < products.size(); i++) { + assertEquals(3 + i, products.get(i).productId.intValue()); + } + } + + @Test + public void testComplexInheritance() { + ProductViewInheritedComplex view = new ProductViewInheritedComplex(); + List<ProductViewInheritedComplex> products = db.from(view).select(); + assertEquals(5, products.size()); + for (int i = 0; i < products.size(); i++) { + assertEquals(3 + i, products.get(i).productId.intValue()); + assertTrue(!StringUtils.isNullOrEmpty(products.get(i).productName)); + } + } + + @Test + public void testCreateViewFromQuery() { + // create view from query + ProductAnnotationOnly product = new ProductAnnotationOnly(); + db.from(product).where(product.productId).exceeds(2L).and(product.productId).atMost(7L).createView(ProductViewFromQuery.class); + + // select from the created view + ProductViewFromQuery view = new ProductViewFromQuery(); + List<ProductViewFromQuery> products = db.from(view).select(); + assertEquals(5, products.size()); + for (int i = 0; i < products.size(); i++) { + assertEquals(3 + i, products.get(i).productId.intValue()); + } + + // replace the view + db.from(product).where(product.productId).exceeds(3L).and(product.productId).atMost(8L).replaceView(ProductViewFromQuery.class); + + // select from the replaced view + products = db.from(view).select(); + assertEquals(5, products.size()); + for (int i = 0; i < products.size(); i++) { + assertEquals(4 + i, products.get(i).productId.intValue()); + } + } +} diff --git a/src/test/java/com/iciql/test/models/BooleanModel.java b/src/test/java/com/iciql/test/models/BooleanModel.java new file mode 100644 index 0000000..d22e3c1 --- /dev/null +++ b/src/test/java/com/iciql/test/models/BooleanModel.java @@ -0,0 +1,73 @@ +/*
+ * Copyright 2011 James Moger.
+ *
+ * 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.iciql.test.models;
+
+import java.util.Arrays;
+import java.util.List;
+
+import com.iciql.Iciql.IQColumn;
+import com.iciql.Iciql.IQTable;
+
+/**
+ * Boolean types model.
+ */
+@IQTable(name = "BooleanTest")
+public class BooleanModel {
+
+ @IQColumn(primaryKey = true)
+ public Integer id;
+
+ @IQColumn
+ public Boolean mybool;
+
+ public BooleanModel() {
+ }
+
+ BooleanModel(int id, boolean val) {
+ this.id = id;
+ this.mybool = val;
+ }
+
+ public static List<BooleanModel> getList() {
+ return Arrays.asList(new BooleanModel(1, true), new BooleanModel(2, false),
+ new BooleanModel(3, true), new BooleanModel(4, false));
+ }
+
+ /**
+ * Test boolean as int
+ */
+ @IQTable(name = "BooleanTest")
+ public static class BooleanAsIntModel {
+ @IQColumn(primaryKey = true)
+ public Integer id;
+
+ @IQColumn
+ public Integer mybool;
+
+ public BooleanAsIntModel() {
+ }
+
+ BooleanAsIntModel(int id, boolean val) {
+ this.id = id;
+ this.mybool = val ? 1 : 0;
+ }
+
+ public static List<BooleanAsIntModel> getList() {
+ return Arrays.asList(new BooleanAsIntModel(1, true), new BooleanAsIntModel(2, false),
+ new BooleanAsIntModel(3, true), new BooleanAsIntModel(4, false));
+ }
+ }
+}
diff --git a/src/test/java/com/iciql/test/models/CategoryAnnotationOnly.java b/src/test/java/com/iciql/test/models/CategoryAnnotationOnly.java new file mode 100644 index 0000000..b96ab04 --- /dev/null +++ b/src/test/java/com/iciql/test/models/CategoryAnnotationOnly.java @@ -0,0 +1,70 @@ +/* + * Copyright 2012 Frédéric Gaillard. + * Copyright 2012 James Moger. + * + * 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.iciql.test.models; + +import java.util.Arrays; +import java.util.List; + +import com.iciql.Iciql.IQColumn; +import com.iciql.Iciql.IQContraintUnique; +import com.iciql.Iciql.IQTable; + +/** + * A table containing category data. + */ + +@IQTable(name = "AnnotatedCategory", primaryKey = "id") +// @IQIndex(value = "categ", type=IndexType.UNIQUE) +@IQContraintUnique(uniqueColumns = { "categ" }) +public class CategoryAnnotationOnly { + + @IQColumn(name = "id", autoIncrement = true) + public Long categoryId; + + @IQColumn(name = "categ", length = 15, trim = true) + public String category; + + public CategoryAnnotationOnly() { + // public constructor + } + + private CategoryAnnotationOnly(long categoryId, String category) { + this.categoryId = categoryId; + this.category = category; + } + + private static CategoryAnnotationOnly create(int categoryId, String category) { + return new CategoryAnnotationOnly(categoryId, category); + } + + public static List<CategoryAnnotationOnly> getList() { + CategoryAnnotationOnly[] list = { + create(1, "Beverages"), + create(2, "Condiments"), + create(3, "Produce"), + create(4, "Meat/Poultry"), + create(5,"Seafood") + }; + return Arrays.asList(list); + } + + public String toString() { + return category; + } + +} diff --git a/src/test/java/com/iciql/test/models/ComplexObject.java b/src/test/java/com/iciql/test/models/ComplexObject.java new file mode 100644 index 0000000..ce9b9ec --- /dev/null +++ b/src/test/java/com/iciql/test/models/ComplexObject.java @@ -0,0 +1,66 @@ +/* + * Copyright 2004-2011 H2 Group. + * Copyright 2011 James Moger. + * + * 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.iciql.test.models; + +import static com.iciql.Define.length; +import static com.iciql.Define.primaryKey; + +import java.math.BigDecimal; +import java.sql.Time; +import java.sql.Timestamp; +import java.util.Arrays; +import java.util.Date; +import java.util.List; + +import com.iciql.Iciql; + +/** + * A table containing all possible data types. + */ + +public class ComplexObject implements Iciql { + public Integer id; + public Long amount; + public String name; + public BigDecimal value; + public Date birthday; + public Time time; + public Timestamp created; + + static ComplexObject build(Integer id, boolean isNull) { + ComplexObject obj = new ComplexObject(); + obj.id = id; + obj.amount = isNull ? null : Long.valueOf(1); + obj.name = isNull ? null : "hello"; + obj.value = isNull ? null : new BigDecimal("1"); + obj.birthday = isNull ? null : java.sql.Date.valueOf("2001-01-01"); + obj.time = isNull ? null : Time.valueOf("10:20:30"); + obj.created = isNull ? null : Timestamp.valueOf("2002-02-02 02:02:02"); + return obj; + } + + public void defineIQ() { + primaryKey(id); + length(name, 25); + } + + public static List<ComplexObject> getList() { + return Arrays.asList(new ComplexObject[] { build(0, true), build(1, false) }); + } + +} diff --git a/src/test/java/com/iciql/test/models/Customer.java b/src/test/java/com/iciql/test/models/Customer.java new file mode 100644 index 0000000..ae8e40d --- /dev/null +++ b/src/test/java/com/iciql/test/models/Customer.java @@ -0,0 +1,57 @@ +/*
+ * Copyright 2004-2011 H2 Group.
+ * Copyright 2011 James Moger.
+ *
+ * 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.iciql.test.models;
+
+import java.util.Arrays;
+import java.util.List;
+
+import com.iciql.Iciql.IQColumn;
+import com.iciql.Iciql.IQTable;
+
+/**
+ * A table containing customer data.
+ */
+@IQTable
+public class Customer {
+
+ @IQColumn(length = 25)
+ public String customerId;
+
+ @IQColumn(length = 2)
+ public String region;
+
+ public Customer() {
+ // public constructor
+ }
+
+ public Customer(String customerId, String region) {
+ this.customerId = customerId;
+ this.region = region;
+ }
+
+ 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);
+ }
+
+}
diff --git a/src/test/java/com/iciql/test/models/DefaultValuesModel.java b/src/test/java/com/iciql/test/models/DefaultValuesModel.java new file mode 100644 index 0000000..cb3b421 --- /dev/null +++ b/src/test/java/com/iciql/test/models/DefaultValuesModel.java @@ -0,0 +1,58 @@ +/*
+ * Copyright 2011 James Moger.
+ *
+ * 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.iciql.test.models;
+
+import java.util.Date;
+
+import com.iciql.Iciql.EnumType;
+import com.iciql.Iciql.IQColumn;
+import com.iciql.Iciql.IQEnum;
+import com.iciql.Iciql.IQTable;
+import com.iciql.test.models.EnumModels.Tree;
+
+/**
+ * Default values model.
+ */
+@IQTable(name = "DefaultValuesTest")
+public class DefaultValuesModel {
+
+ @IQColumn(primaryKey = true, autoIncrement = true)
+ public Long myLong;
+
+ @SuppressWarnings("deprecation")
+ @IQColumn
+ public Date myDate = new Date(100, 7, 1);
+
+ @IQColumn
+ public Integer myInteger = 12345;
+
+ @IQColumn
+ public Tree myEnumIdTree = Tree.WALNUT;
+
+ @IQColumn
+ @IQEnum(EnumType.NAME)
+ public Tree myNameTree = Tree.MAPLE;
+
+ @IQColumn
+ @IQEnum(EnumType.ORDINAL)
+ public Tree myOrdinalTree = Tree.PINE;
+
+ @IQColumn(nullable = true)
+ public Tree myNullTree;
+
+ public DefaultValuesModel() {
+ }
+}
diff --git a/src/test/java/com/iciql/test/models/EnumModels.java b/src/test/java/com/iciql/test/models/EnumModels.java new file mode 100644 index 0000000..a865f6c --- /dev/null +++ b/src/test/java/com/iciql/test/models/EnumModels.java @@ -0,0 +1,157 @@ +/*
+ * Copyright 2011 James Moger.
+ *
+ * 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.iciql.test.models;
+
+import java.util.Arrays;
+import java.util.List;
+
+import com.iciql.Iciql.EnumId;
+import com.iciql.Iciql.EnumType;
+import com.iciql.Iciql.IQColumn;
+import com.iciql.Iciql.IQEnum;
+import com.iciql.Iciql.IQTable;
+
+/**
+ * Container for reusable enum model classes which exercise the 3 supported
+ * types.
+ */
+public abstract class EnumModels {
+
+ /**
+ * Test of @IQEnum annotated enumeration. This strategy is the default
+ * strategy for all fields of the Tree enum.
+ *
+ * Individual Tree field declarations can override this strategy by
+ * specifying a different @IQEnum annotation.
+ *
+ * Here ORDINAL specifies that this enum will be mapped to an INT column.
+ */
+ @IQEnum(EnumType.ENUMID)
+ public enum Tree implements EnumId {
+ PINE(10), OAK(20), BIRCH(30), WALNUT(40), MAPLE(50);
+
+ private int enumid;
+
+ Tree(int id) {
+ this.enumid = id;
+ }
+
+ @Override
+ public int enumId() {
+ return enumid;
+ }
+ }
+
+ @IQColumn(primaryKey = true)
+ public Integer id;
+
+ public abstract Tree tree();
+
+ /**
+ * Test model for enum-as-enumid.
+ */
+ @IQTable(inheritColumns = true)
+ public static class EnumIdModel extends EnumModels {
+
+ // no need to specify ENUMID type as the enumeration definition
+ // specifies it.
+ @IQColumn
+ private Tree tree;
+
+ public EnumIdModel() {
+ }
+
+ public EnumIdModel(int id, Tree tree) {
+ this.id = id;
+ this.tree = tree;
+ }
+
+ @Override
+ public Tree tree() {
+ return tree;
+ }
+
+ public static List<EnumIdModel> createList() {
+ return Arrays.asList(new EnumIdModel(400, Tree.WALNUT), new EnumIdModel(200, Tree.OAK),
+ new EnumIdModel(500, Tree.MAPLE), new EnumIdModel(300, Tree.BIRCH), new EnumIdModel(100,
+ Tree.PINE));
+ }
+ }
+
+ /**
+ * Test model for enum-as-ordinal.
+ */
+ @IQTable(inheritColumns = true)
+ public static class EnumOrdinalModel extends EnumModels {
+
+ // override the enumtype to ordinal
+ @IQEnum(EnumType.ORDINAL)
+ @IQColumn
+ private Tree tree;
+
+ public EnumOrdinalModel() {
+ }
+
+ public EnumOrdinalModel(int id, Tree tree) {
+ this.id = id;
+ this.tree = tree;
+ }
+
+ @Override
+ public Tree tree() {
+ return tree;
+ }
+
+ public static List<EnumOrdinalModel> createList() {
+ return Arrays.asList(new EnumOrdinalModel(400, Tree.WALNUT), new EnumOrdinalModel(200, Tree.OAK),
+ new EnumOrdinalModel(500, Tree.MAPLE), new EnumOrdinalModel(300, Tree.BIRCH),
+ new EnumOrdinalModel(100, Tree.PINE));
+ }
+ }
+
+ /**
+ * Test model for enum-as-string.
+ */
+ @IQTable(inheritColumns = true)
+ public static class EnumStringModel extends EnumModels {
+
+ // override the enumtype to string
+ // ensure that we specify a length so that the column is VARCHAR
+ @IQEnum(EnumType.NAME)
+ @IQColumn(length = 25)
+ private Tree tree;
+
+ public EnumStringModel() {
+ }
+
+ public EnumStringModel(int id, Tree tree) {
+ this.id = id;
+ this.tree = tree;
+ }
+
+ @Override
+ public Tree tree() {
+ return tree;
+ }
+
+ public static List<EnumStringModel> createList() {
+ return Arrays.asList(new EnumStringModel(400, Tree.WALNUT), new EnumStringModel(200, Tree.OAK),
+ new EnumStringModel(500, Tree.MAPLE), new EnumStringModel(300, Tree.BIRCH),
+ new EnumStringModel(100, Tree.PINE));
+ }
+ }
+}
diff --git a/src/test/java/com/iciql/test/models/MultipleBoolsModel.java b/src/test/java/com/iciql/test/models/MultipleBoolsModel.java new file mode 100644 index 0000000..7bc429c --- /dev/null +++ b/src/test/java/com/iciql/test/models/MultipleBoolsModel.java @@ -0,0 +1,40 @@ +package com.iciql.test.models;
+
+import java.util.Arrays;
+import java.util.List;
+
+import com.iciql.Iciql.IQColumn;
+import com.iciql.Iciql.IQTable;
+
+/**
+ * Model class to test the runtime exception of too many primitive boolean
+ * fields in the model.
+ *
+ * @author James Moger
+ *
+ */
+@IQTable
+public class MultipleBoolsModel {
+
+ @IQColumn(autoIncrement = true, primaryKey = true)
+ public int id;
+
+ @IQColumn
+ public boolean a;
+
+ @IQColumn
+ public boolean b;
+
+ public MultipleBoolsModel() {
+ }
+
+ public MultipleBoolsModel(boolean a, boolean b) {
+ this.a = a;
+ this.b = b;
+ }
+
+ public static List<MultipleBoolsModel> getList() {
+ return Arrays.asList(new MultipleBoolsModel(true, true), new MultipleBoolsModel(true, false),
+ new MultipleBoolsModel(true, false), new MultipleBoolsModel(false, false));
+ }
+}
\ No newline at end of file diff --git a/src/test/java/com/iciql/test/models/Order.java b/src/test/java/com/iciql/test/models/Order.java new file mode 100644 index 0000000..1fa9097 --- /dev/null +++ b/src/test/java/com/iciql/test/models/Order.java @@ -0,0 +1,73 @@ +/*
+ * Copyright 2004-2011 H2 Group.
+ * Copyright 2011 James Moger.
+ *
+ * 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.iciql.test.models;
+
+import static com.iciql.Define.length;
+import static com.iciql.Define.primaryKey;
+import static com.iciql.Define.scale;
+import static com.iciql.Define.tableName;
+
+import java.math.BigDecimal;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+
+import com.iciql.Iciql;
+
+/**
+ * A table containing order data.
+ */
+
+public class Order implements Iciql {
+ public String customerId;
+ public Integer orderId;
+ public Date orderDate;
+ public BigDecimal total;
+
+ public Order(String customerId, Integer orderId, String total, String orderDate) {
+ this.customerId = customerId;
+ this.orderId = orderId;
+ this.total = new BigDecimal(total);
+ this.orderDate = java.sql.Date.valueOf(orderDate);
+ }
+
+ public Order() {
+ // public constructor
+ }
+
+ public void defineIQ() {
+ tableName("Orders");
+ length(customerId, 25);
+ length(total, 10);
+ scale(total, 2);
+ primaryKey(customerId, orderId);
+ }
+
+ public static List<Order> getList() {
+ Order[] list = { new Order("ALFKI", 10702, "330.00", "2007-01-02"),
+ new Order("ALFKI", 10952, "471.20", "2007-02-03"),
+ new Order("ANATR", 10308, "88.80", "2007-01-03"),
+ new Order("ANATR", 10625, "479.75", "2007-03-03"),
+ new Order("ANATR", 10759, "320.00", "2007-04-01"),
+ new Order("ANTON", 10365, "403.20", "2007-02-13"),
+ new Order("ANTON", 10682, "375.50", "2007-03-13"),
+ new Order("ANTON", 10355, "480.00", "2007-04-11") };
+ return Arrays.asList(list);
+ }
+
+}
diff --git a/src/test/java/com/iciql/test/models/PrimitivesModel.java b/src/test/java/com/iciql/test/models/PrimitivesModel.java new file mode 100644 index 0000000..44e8b9b --- /dev/null +++ b/src/test/java/com/iciql/test/models/PrimitivesModel.java @@ -0,0 +1,90 @@ +/*
+ * Copyright 2011 James Moger.
+ *
+ * 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.iciql.test.models;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+
+import com.iciql.Iciql.IQColumn;
+import com.iciql.Iciql.IQTable;
+import com.iciql.test.IciqlSuite;
+
+/**
+ * Primitive types model.
+ */
+@IQTable(name = "PrimitivesTest")
+public class PrimitivesModel {
+
+ @IQColumn(primaryKey = true)
+ public long myLong;
+
+ @IQColumn
+ public int myInteger;
+
+ @IQColumn
+ public short myShort;
+
+ @IQColumn
+ public byte myByte;
+
+ @IQColumn
+ public boolean myBoolean;
+
+ @IQColumn
+ public double myDouble;
+
+ @IQColumn
+ public float myFloat;
+
+ public PrimitivesModel() {
+ Random rand = new Random();
+ myLong = rand.nextLong();
+ myInteger = rand.nextInt();
+ myShort = (short) rand.nextInt(Short.MAX_VALUE);
+ myByte = (byte) rand.nextInt(Byte.MAX_VALUE);
+ myBoolean = rand.nextInt(1) == 1;
+ myDouble = rand.nextDouble();
+ myFloat = rand.nextFloat();
+ }
+
+ public boolean equivalentTo(PrimitivesModel p) {
+ boolean same = true;
+ same &= myLong == p.myLong;
+ same &= myInteger == p.myInteger;
+ same &= myShort == p.myShort;
+ same &= myByte == p.myByte;
+ same &= myBoolean == p.myBoolean;
+ same &= IciqlSuite.equivalentTo(myDouble, p.myDouble);
+ same &= IciqlSuite.equivalentTo(myFloat, p.myFloat);
+ return same;
+ }
+
+ public static List<PrimitivesModel> getList() {
+ List<PrimitivesModel> list = new ArrayList<PrimitivesModel>();
+ for (int i = 1; i <= 10; i++) {
+ PrimitivesModel p = new PrimitivesModel();
+ p.myLong = i;
+ list.add(p);
+ }
+ return list;
+ }
+
+ @Override
+ public String toString() {
+ return String.valueOf(myLong);
+ }
+}
diff --git a/src/test/java/com/iciql/test/models/Product.java b/src/test/java/com/iciql/test/models/Product.java new file mode 100644 index 0000000..241a3d3 --- /dev/null +++ b/src/test/java/com/iciql/test/models/Product.java @@ -0,0 +1,85 @@ +/*
+ * Copyright 2004-2011 H2 Group.
+ * Copyright 2011 James Moger.
+ *
+ * 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.iciql.test.models;
+
+import static com.iciql.Define.index;
+import static com.iciql.Define.length;
+import static com.iciql.Define.primaryKey;
+import static com.iciql.Define.tableName;
+
+import java.util.Arrays;
+import java.util.List;
+
+import com.iciql.Iciql;
+
+/**
+ * A table containing product data.
+ */
+
+public class Product implements Iciql {
+
+ public Integer productId;
+ public String productName;
+ public String category;
+ public Double unitPrice;
+ public Integer unitsInStock;
+
+ public Product() {
+ // public constructor
+ }
+
+ private Product(int productId, String productName, String category, double unitPrice, int unitsInStock) {
+ this.productId = productId;
+ this.productName = productName;
+ this.category = category;
+ this.unitPrice = unitPrice;
+ this.unitsInStock = unitsInStock;
+ }
+
+ public void defineIQ() {
+ tableName("Product");
+ primaryKey(productId);
+ length(productName, 255);
+ length(category, 255);
+ index("MyIndex", IndexType.STANDARD, productName, category);
+ }
+
+ private static Product create(int productId, String productName, String category, double unitPrice,
+ int unitsInStock) {
+ return new Product(productId, productName, category, unitPrice, unitsInStock);
+ }
+
+ public static List<Product> getList() {
+ Product[] list = { create(1, "Chai", "Beverages", 18, 39), create(2, "Chang", "Beverages", 19.0, 17),
+ create(3, "Aniseed Syrup", "Condiments", 10.0, 13),
+ create(4, "Chef Anton's Cajun Seasoning", "Condiments", 22.0, 53),
+ create(5, "Chef Anton's Gumbo Mix", "Condiments", 21.3500, 0),
+ create(6, "Grandma's Boysenberry Spread", "Condiments", 25.0, 120),
+ create(7, "Uncle Bob's Organic Dried Pears", "Produce", 30.0, 15),
+ create(8, "Northwoods Cranberry Sauce", "Condiments", 40.0, 6),
+ create(9, "Mishi Kobe Niku", "Meat/Poultry", 97.0, 29),
+ create(10, "Ikura", "Seafood", 31.0, 31), };
+
+ return Arrays.asList(list);
+ }
+
+ public String toString() {
+ return productName + ": " + unitsInStock;
+ }
+
+}
diff --git a/src/test/java/com/iciql/test/models/ProductAnnotationOnly.java b/src/test/java/com/iciql/test/models/ProductAnnotationOnly.java new file mode 100644 index 0000000..1f6b4e2 --- /dev/null +++ b/src/test/java/com/iciql/test/models/ProductAnnotationOnly.java @@ -0,0 +1,94 @@ +/* + * Copyright 2004-2011 H2 Group. + * Copyright 2011 James Moger. + * + * 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.iciql.test.models; + +import java.util.Arrays; +import java.util.List; + +import com.iciql.Iciql.IQColumn; +import com.iciql.Iciql.IQIndex; +import com.iciql.Iciql.IQIndexes; +import com.iciql.Iciql.IQTable; +import com.iciql.Iciql.IndexType; + +/** + * A table containing product data. + */ + +@IQTable(name = "AnnotatedProduct", primaryKey = "id") +@IQIndexes({ @IQIndex({ "name", "cat" }), @IQIndex(name = "nameidx", type = IndexType.HASH, value = "name") }) +public class ProductAnnotationOnly { + + public String unmappedField; + + @IQColumn(name = "id", autoIncrement = true) + public Long productId; + + @IQColumn(name = "cat", length = 15, trim = true) + public String category; + + @IQColumn(name = "name", length = 50) + public String productName; + + @SuppressWarnings("unused") + @IQColumn + private Double unitPrice; + + @IQColumn + private Integer unitsInStock; + + public ProductAnnotationOnly() { + // public constructor + } + + private ProductAnnotationOnly(long productId, String productName, String category, double unitPrice, + int unitsInStock, String unmappedField) { + this.productId = productId; + this.productName = productName; + this.category = category; + this.unitPrice = unitPrice; + this.unitsInStock = unitsInStock; + this.unmappedField = unmappedField; + } + + private static ProductAnnotationOnly create(int productId, String productName, String category, + double unitPrice, int unitsInStock, String unmappedField) { + return new ProductAnnotationOnly(productId, productName, category, unitPrice, unitsInStock, + unmappedField); + } + + public static List<ProductAnnotationOnly> getList() { + String unmappedField = "unmapped"; + ProductAnnotationOnly[] list = { create(1, "Chai", "Beverages", 18, 39, unmappedField), + create(2, "Chang", "Beverages", 19.0, 17, unmappedField), + create(3, "Aniseed Syrup", "Condiments", 10.0, 13, unmappedField), + create(4, "Chef Anton's Cajun Seasoning", "Condiments", 22.0, 53, unmappedField), + create(5, "Chef Anton's Gumbo Mix", "Condiments", 21.3500, 0, unmappedField), + create(6, "Grandma's Boysenberry Spread", "Condiments", 25.0, 120, unmappedField), + create(7, "Uncle Bob's Organic Dried Pears", "Produce", 30.0, 15, unmappedField), + create(8, "Northwoods Cranberry Sauce", "Condiments", 40.0, 6, unmappedField), + create(9, "Mishi Kobe Niku", "Meat/Poultry", 97.0, 29, unmappedField), + create(10, "Ikura", "Seafood", 31.0, 31, unmappedField), }; + return Arrays.asList(list); + } + + public String toString() { + return productName + ": " + unitsInStock; + } + +} diff --git a/src/test/java/com/iciql/test/models/ProductAnnotationOnlyWithForeignKey.java b/src/test/java/com/iciql/test/models/ProductAnnotationOnlyWithForeignKey.java new file mode 100644 index 0000000..4268a89 --- /dev/null +++ b/src/test/java/com/iciql/test/models/ProductAnnotationOnlyWithForeignKey.java @@ -0,0 +1,102 @@ +/* + * Copyright 2012 Frédéric Gaillard. + * Copyright 2012 James Moger. + * + * 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.iciql.test.models; + +import java.util.Arrays; +import java.util.List; + +import com.iciql.Iciql.ConstraintDeleteType; +import com.iciql.Iciql.IQColumn; +import com.iciql.Iciql.IQContraintForeignKey; +import com.iciql.Iciql.IQIndex; +import com.iciql.Iciql.IQIndexes; +import com.iciql.Iciql.IQTable; +import com.iciql.Iciql.IndexType; + +/** + * A table containing product data. + */ + +@IQTable(name = "AnnotatedProduct", primaryKey = "id") +@IQIndexes({ @IQIndex({ "name", "cat" }), @IQIndex(name = "nameidx", type = IndexType.HASH, value = "name") }) +@IQContraintForeignKey( + foreignColumns= { "cat" }, + referenceName = "AnnotatedCategory", + referenceColumns = { "categ" }, + deleteType = ConstraintDeleteType.CASCADE +) +public class ProductAnnotationOnlyWithForeignKey { + + public String unmappedField; + + @IQColumn(name = "id", autoIncrement = true) + public Long productId; + + @IQColumn(name = "cat", length = 15, trim = true) + public String category; + + @IQColumn(name = "name", length = 50) + public String productName; + + @SuppressWarnings("unused") + @IQColumn + private Double unitPrice; + + @IQColumn + private Integer unitsInStock; + + public ProductAnnotationOnlyWithForeignKey() { + // public constructor + } + + private ProductAnnotationOnlyWithForeignKey(long productId, String productName, String category, double unitPrice, + int unitsInStock, String unmappedField) { + this.productId = productId; + this.productName = productName; + this.category = category; + this.unitPrice = unitPrice; + this.unitsInStock = unitsInStock; + this.unmappedField = unmappedField; + } + + private static ProductAnnotationOnlyWithForeignKey create(int productId, String productName, String category, + double unitPrice, int unitsInStock, String unmappedField) { + return new ProductAnnotationOnlyWithForeignKey(productId, productName, category, unitPrice, unitsInStock, + unmappedField); + } + + public static List<ProductAnnotationOnlyWithForeignKey> getList() { + String unmappedField = "unmapped"; + ProductAnnotationOnlyWithForeignKey[] list = { create(1, "Chai", "Beverages", 18, 39, unmappedField), + create(2, "Chang", "Beverages", 19.0, 17, unmappedField), + create(3, "Aniseed Syrup", "Condiments", 10.0, 13, unmappedField), + create(4, "Chef Anton's Cajun Seasoning", "Condiments", 22.0, 53, unmappedField), + create(5, "Chef Anton's Gumbo Mix", "Condiments", 21.3500, 0, unmappedField), + create(6, "Grandma's Boysenberry Spread", "Condiments", 25.0, 120, unmappedField), + create(7, "Uncle Bob's Organic Dried Pears", "Produce", 30.0, 15, unmappedField), + create(8, "Northwoods Cranberry Sauce", "Condiments", 40.0, 6, unmappedField), + create(9, "Mishi Kobe Niku", "Meat/Poultry", 97.0, 29, unmappedField), + create(10, "Ikura", "Seafood", 31.0, 31, unmappedField), }; + return Arrays.asList(list); + } + + public String toString() { + return productName + ": " + unitsInStock; + } + +} diff --git a/src/test/java/com/iciql/test/models/ProductInheritedAnnotation.java b/src/test/java/com/iciql/test/models/ProductInheritedAnnotation.java new file mode 100644 index 0000000..112f4ef --- /dev/null +++ b/src/test/java/com/iciql/test/models/ProductInheritedAnnotation.java @@ -0,0 +1,64 @@ +/* + * Copyright 2004-2011 H2 Group. + * Copyright 2011 James Moger. + * + * 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.iciql.test.models; + +import java.util.Arrays; +import java.util.List; + +import com.iciql.Iciql.IQTable; + +/** + * This class inherits all its fields from a parent class which has annotated + * columns. The IQTable annotation of the parent class is ignored and only the + * IQTable annotation of this class matters. However, this table inherits + * IQColumns from its super class. + */ +@IQTable(inheritColumns = true, annotationsOnly = false) +public class ProductInheritedAnnotation extends ProductMixedAnnotation { + + public ProductInheritedAnnotation() { + // public constructor + } + + private ProductInheritedAnnotation(int productId, String productName, String category, double unitPrice, + int unitsInStock, String mappedField) { + super(productId, productName, category, unitPrice, unitsInStock, mappedField); + } + + private static ProductInheritedAnnotation create(int productId, String productName, String category, + double unitPrice, int unitsInStock, String mappedField) { + return new ProductInheritedAnnotation(productId, productName, category, unitPrice, unitsInStock, + mappedField); + } + + public static List<ProductInheritedAnnotation> getData() { + String mappedField = "mapped"; + ProductInheritedAnnotation[] list = { create(1, "Chai", "Beverages", 18, 39, mappedField), + create(2, "Chang", "Beverages", 19.0, 17, mappedField), + create(3, "Aniseed Syrup", "Condiments", 10.0, 13, mappedField), + create(4, "Chef Anton's Cajun Seasoning", "Condiments", 22.0, 53, mappedField), + create(5, "Chef Anton's Gumbo Mix", "Condiments", 21.3500, 0, mappedField), + create(6, "Grandma's Boysenberry Spread", "Condiments", 25.0, 120, mappedField), + create(7, "Uncle Bob's Organic Dried Pears", "Produce", 30.0, 15, mappedField), + create(8, "Northwoods Cranberry Sauce", "Condiments", 40.0, 6, mappedField), + create(9, "Mishi Kobe Niku", "Meat/Poultry", 97.0, 29, mappedField), + create(10, "Ikura", "Seafood", 31.0, 31, mappedField), }; + return Arrays.asList(list); + } + +} diff --git a/src/test/java/com/iciql/test/models/ProductMixedAnnotation.java b/src/test/java/com/iciql/test/models/ProductMixedAnnotation.java new file mode 100644 index 0000000..a893a69 --- /dev/null +++ b/src/test/java/com/iciql/test/models/ProductMixedAnnotation.java @@ -0,0 +1,104 @@ +/* + * Copyright 2004-2011 H2 Group. + * Copyright 2011 James Moger. + * + * 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.iciql.test.models; + +import java.util.Arrays; +import java.util.List; + +import com.iciql.Define; +import com.iciql.Iciql; +import com.iciql.Iciql.IQIndex; +import com.iciql.Iciql.IQTable; + +/** + * A table containing product data. + */ + +@IQTable(annotationsOnly = false) +@IQIndex({ "name", "cat" }) +public class ProductMixedAnnotation implements Iciql { + + public Double unitPrice; + public Integer unitsInStock; + public String mappedField; + + @IQIgnore + public String productDescription; + + @IQColumn(name = "cat", length = 255) + public String category; + + @IQColumn(name = "id", primaryKey = true) + private Integer productId; + + @IQColumn(name = "name", length = 255) + private String productName; + + public ProductMixedAnnotation() { + // public constructor + } + + protected ProductMixedAnnotation(int productId, String productName, String category, double unitPrice, + int unitsInStock, String mappedField) { + this.productId = productId; + this.productName = productName; + this.category = category; + this.unitPrice = unitPrice; + this.unitsInStock = unitsInStock; + this.mappedField = mappedField; + this.productDescription = category + ": " + productName; + } + + private static ProductMixedAnnotation create(int productId, String productName, String category, + double unitPrice, int unitsInStock, String mappedField) { + return new ProductMixedAnnotation(productId, productName, category, unitPrice, unitsInStock, + mappedField); + } + + public static List<ProductMixedAnnotation> getList() { + String mappedField = "mapped"; + ProductMixedAnnotation[] list = { create(1, "Chai", "Beverages", 18, 39, mappedField), + create(2, "Chang", "Beverages", 19.0, 17, mappedField), + create(3, "Aniseed Syrup", "Condiments", 10.0, 13, mappedField), + create(4, "Chef Anton's Cajun Seasoning", "Condiments", 22.0, 53, mappedField), + create(5, "Chef Anton's Gumbo Mix", "Condiments", 21.3500, 0, mappedField), + create(6, "Grandma's Boysenberry Spread", "Condiments", 25.0, 120, mappedField), + create(7, "Uncle Bob's Organic Dried Pears", "Produce", 30.0, 15, mappedField), + create(8, "Northwoods Cranberry Sauce", "Condiments", 40.0, 6, mappedField), + create(9, "Mishi Kobe Niku", "Meat/Poultry", 97.0, 29, mappedField), + create(10, "Ikura", "Seafood", 31.0, 31, mappedField), }; + return Arrays.asList(list); + } + + public String toString() { + return productName + ": " + unitsInStock; + } + + public int id() { + return productId; + } + + public String name() { + return productName; + } + + @Override + public void defineIQ() { + Define.length(mappedField, 25); + } +} diff --git a/src/test/java/com/iciql/test/models/ProductNoCreateTable.java b/src/test/java/com/iciql/test/models/ProductNoCreateTable.java new file mode 100644 index 0000000..cbf96e9 --- /dev/null +++ b/src/test/java/com/iciql/test/models/ProductNoCreateTable.java @@ -0,0 +1,59 @@ +/* + * Copyright 2004-2011 H2 Group. + * Copyright 2011 James Moger. + * + * 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.iciql.test.models; + +import java.util.Arrays; +import java.util.List; + +import com.iciql.Iciql.IQColumn; +import com.iciql.Iciql.IQTable; + +/** + * A table containing product data. + */ + +@IQTable(create = false) +public class ProductNoCreateTable { + + @SuppressWarnings("unused") + @IQColumn(name = "id") + private Integer productId; + + @SuppressWarnings("unused") + @IQColumn(name = "name") + private String productName; + + public ProductNoCreateTable() { + // public constructor + } + + private ProductNoCreateTable(int productId, String productName) { + this.productId = productId; + this.productName = productName; + } + + private static ProductNoCreateTable create(int productId, String productName) { + return new ProductNoCreateTable(productId, productName); + } + + public static List<ProductNoCreateTable> getList() { + ProductNoCreateTable[] list = { create(1, "Chai"), create(2, "Chang") }; + return Arrays.asList(list); + } + +} diff --git a/src/test/java/com/iciql/test/models/ProductView.java b/src/test/java/com/iciql/test/models/ProductView.java new file mode 100644 index 0000000..2efe9eb --- /dev/null +++ b/src/test/java/com/iciql/test/models/ProductView.java @@ -0,0 +1,47 @@ +/* + * Copyright 2012 James Moger. + * + * 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.iciql.test.models; + +import com.iciql.Iciql.IQColumn; +import com.iciql.Iciql.IQConstraint; +import com.iciql.Iciql.IQView; + +/** + * A view containing product data. + */ + +@IQView(name = "AnnotatedProductView", tableName = "AnnotatedProduct") +public class ProductView { + + public String unmappedField; + + @IQColumn(name = "id", autoIncrement = true) + @IQConstraint("this <= 7 AND this > 2") + public Long productId; + + @IQColumn(name = "name") + public String productName; + + public ProductView() { + // public constructor + } + + public String toString() { + return productName + " (" + productId + ")"; + } + +} diff --git a/src/test/java/com/iciql/test/models/ProductViewFromQuery.java b/src/test/java/com/iciql/test/models/ProductViewFromQuery.java new file mode 100644 index 0000000..2f2f194 --- /dev/null +++ b/src/test/java/com/iciql/test/models/ProductViewFromQuery.java @@ -0,0 +1,42 @@ +/* + * Copyright 2012 James Moger. + * + * 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.iciql.test.models; + +import com.iciql.Iciql.IQColumn; +import com.iciql.Iciql.IQView; + +/** + * A view containing product data. + */ + +@IQView(name = "AnnotatedProductViewInherited", inheritColumns = true) +public class ProductViewFromQuery extends ProductAnnotationOnly { + + public String unmappedField; + + @IQColumn(name = "id") + public Long productId; + + public ProductViewFromQuery() { + // public constructor + } + + public String toString() { + return productName + " (" + productId + ")"; + } + +} diff --git a/src/test/java/com/iciql/test/models/ProductViewInherited.java b/src/test/java/com/iciql/test/models/ProductViewInherited.java new file mode 100644 index 0000000..e9c274b --- /dev/null +++ b/src/test/java/com/iciql/test/models/ProductViewInherited.java @@ -0,0 +1,44 @@ +/* + * Copyright 2012 James Moger. + * + * 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.iciql.test.models; + +import com.iciql.Iciql.IQColumn; +import com.iciql.Iciql.IQConstraint; +import com.iciql.Iciql.IQView; + +/** + * A view containing product data. + */ + +@IQView(name = "AnnotatedProductViewInherited", inheritColumns = true) +public class ProductViewInherited extends ProductAnnotationOnly { + + public String unmappedField; + + @IQColumn(name = "id", autoIncrement = true) + @IQConstraint("this <= 7 AND this > 2") + public Long productId; + + public ProductViewInherited() { + // public constructor + } + + public String toString() { + return productName + " (" + productId + ")"; + } + +} diff --git a/src/test/java/com/iciql/test/models/ProductViewInheritedComplex.java b/src/test/java/com/iciql/test/models/ProductViewInheritedComplex.java new file mode 100644 index 0000000..55e7ba8 --- /dev/null +++ b/src/test/java/com/iciql/test/models/ProductViewInheritedComplex.java @@ -0,0 +1,28 @@ +/* + * Copyright 2012 James Moger. + * + * 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.iciql.test.models; + +import com.iciql.Iciql.IQView; + +/** + * A view containing product data. + */ + +@IQView(inheritColumns = true) +public class ProductViewInheritedComplex extends ProductViewInherited { + +} diff --git a/src/test/java/com/iciql/test/models/StaticQueries.java b/src/test/java/com/iciql/test/models/StaticQueries.java new file mode 100644 index 0000000..09f84e6 --- /dev/null +++ b/src/test/java/com/iciql/test/models/StaticQueries.java @@ -0,0 +1,87 @@ +/*
+ * Copyright 2011 James Moger.
+ *
+ * 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.iciql.test.models;
+
+import java.sql.Timestamp;
+
+import com.iciql.Iciql.EnumType;
+import com.iciql.Iciql.IQColumn;
+import com.iciql.Iciql.IQEnum;
+import com.iciql.Iciql.IQTable;
+import com.iciql.test.models.EnumModels.Tree;
+
+/**
+ * Static query models.
+ */
+public class StaticQueries {
+
+ @IQTable(name = "StaticQueryTest1")
+ public static class StaticModel1 {
+
+ @IQColumn(primaryKey = true, autoIncrement = true)
+ public Integer id;
+
+ @IQColumn
+ @IQEnum(EnumType.NAME)
+ public Tree myTree;
+
+ @IQColumn
+ public String myString;
+
+ @IQColumn
+ public Boolean myBool;
+
+ @IQColumn
+ public Timestamp myTimestamp;
+
+ @IQColumn
+ public java.sql.Date myDate;
+
+ @IQColumn
+ public java.sql.Time myTime;
+
+ public StaticModel1() {
+ }
+ }
+
+ @IQTable(name = "StaticQueryTest2")
+ public static class StaticModel2 {
+
+ @IQColumn(primaryKey = true, autoIncrement = true)
+ public Integer id;
+
+ @IQColumn
+ @IQEnum(EnumType.ENUMID)
+ public Tree myTree;
+
+ public StaticModel2() {
+ }
+ }
+
+ @IQTable(name = "StaticQueryTest3")
+ public static class StaticModel3 {
+
+ @IQColumn(primaryKey = true, autoIncrement = true)
+ public Integer id;
+
+ @IQColumn
+ @IQEnum(EnumType.ORDINAL)
+ public Tree myTree;
+
+ public StaticModel3() {
+ }
+ }
+}
diff --git a/src/test/java/com/iciql/test/models/SupportedTypes.java b/src/test/java/com/iciql/test/models/SupportedTypes.java new file mode 100644 index 0000000..1aaa833 --- /dev/null +++ b/src/test/java/com/iciql/test/models/SupportedTypes.java @@ -0,0 +1,199 @@ +/* + * Copyright 2004-2011 H2 Group. + * Copyright 2011 James Moger. + * + * 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.iciql.test.models; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.text.SimpleDateFormat; +import java.util.Arrays; +import java.util.List; +import java.util.Random; + +import com.iciql.Iciql.EnumType; +import com.iciql.Iciql.IQColumn; +import com.iciql.Iciql.IQEnum; +import com.iciql.Iciql.IQIndex; +import com.iciql.Iciql.IQIndexes; +import com.iciql.Iciql.IQTable; +import com.iciql.Iciql.IQVersion; +import com.iciql.Iciql.IndexType; +import com.iciql.test.IciqlSuite; +import com.iciql.test.models.EnumModels.Tree; +import com.iciql.util.Utils; + +/** + * A data class that contains a column for each data type. + */ +@IQTable +@IQIndexes({ @IQIndex({ "myLong", "myInteger" }), @IQIndex(type = IndexType.HASH, value = "myString") }) +@IQVersion(1) +public class SupportedTypes { + + public static final SupportedTypes SAMPLE = new SupportedTypes(); + + /** + * Test of plain enumeration. + * + * Each field declaraton of this enum must specify a mapping strategy. + */ + public enum Flower { + ROSE, TULIP, MUM, PETUNIA, MARIGOLD, DAFFODIL; + } + + @IQColumn(primaryKey = true, autoIncrement = true) + public Integer id; + + @IQColumn + private Boolean myBool; + + @IQColumn + private Byte myByte; + + @IQColumn + private Short myShort; + + @IQColumn + private Integer myInteger; + + @IQColumn + private Long myLong; + + @IQColumn + private Float myFloat; + + @IQColumn + private Double myDouble; + + // scale change must match the test value scale + @IQColumn(length = 10, scale = 5) + private BigDecimal myBigDecimal; + + @IQColumn(length = 40) + private String myString; + + @IQColumn + private java.util.Date myUtilDate; + + @IQColumn + private java.sql.Date mySqlDate; + + @IQColumn + private java.sql.Time mySqlTime; + + @IQColumn + private java.sql.Timestamp mySqlTimestamp; + + @IQColumn + private byte[] myBlob; + + // test default enum type NAME + @IQColumn(trim = true, length = 25) + private Flower myDefaultFlower; + + @IQEnum(EnumType.NAME) + @IQColumn(trim = true, length = 25) + private Flower myFavoriteFlower; + + @IQEnum(EnumType.ORDINAL) + @IQColumn + private Flower myOtherFavoriteFlower; + + @IQEnum(EnumType.ORDINAL) + @IQColumn + // override the default enum strategy and use the ordinal value + private Tree myFavoriteTree; + + // @IQEnum is set on the enumeration definition and is shared + // by all uses of Tree as an @IQColumn + @IQColumn + private Tree myOtherFavoriteTree; + + public static List<SupportedTypes> createList() { + List<SupportedTypes> list = Utils.newArrayList(); + long now = System.currentTimeMillis(); + long oneday = 24 * 60 * 60 * 1000L; + for (int i = 0; i < 10; i++) { + list.add(randomValue(now - (i * oneday))); + } + return list; + } + + static SupportedTypes randomValue(long time) { + Random rand = new Random(); + SupportedTypes s = new SupportedTypes(); + s.myBool = new Boolean(rand.nextBoolean()); + s.myByte = new Byte((byte) rand.nextInt(Byte.MAX_VALUE)); + s.myShort = new Short((short) rand.nextInt(Short.MAX_VALUE)); + s.myInteger = new Integer(rand.nextInt()); + s.myLong = new Long(rand.nextLong()); + s.myFloat = new Float(rand.nextFloat()); + s.myDouble = new Double(rand.nextDouble()); + s.myBigDecimal = new BigDecimal(rand.nextDouble()); + // scale must match annotation + s.myBigDecimal = s.myBigDecimal.setScale(5, RoundingMode.UP); + s.myString = Long.toHexString(rand.nextLong()); + s.myUtilDate = new java.util.Date(time); + s.mySqlDate = new java.sql.Date(time); + s.mySqlTime = new java.sql.Time(time); + s.mySqlTimestamp = new java.sql.Timestamp(time); + s.myBlob = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + s.myDefaultFlower = Flower.DAFFODIL; + s.myFavoriteFlower = Flower.MUM; + s.myOtherFavoriteFlower = Flower.MARIGOLD; + s.myFavoriteTree = Tree.BIRCH; + s.myOtherFavoriteTree = Tree.WALNUT; + return s; + } + + public boolean equivalentTo(SupportedTypes s) { + boolean same = true; + same &= myBool.equals(s.myBool); + same &= myByte.equals(s.myByte); + same &= myShort.equals(s.myShort); + same &= myInteger.equals(s.myInteger); + same &= myLong.equals(s.myLong); + same &= IciqlSuite.equivalentTo(myFloat, s.myFloat); + same &= IciqlSuite.equivalentTo(myDouble, s.myDouble); + same &= myBigDecimal.compareTo(s.myBigDecimal) == 0; + SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + same &= df.format(myUtilDate).equals(df.format(s.myUtilDate)); + same &= df.format(mySqlTimestamp).equals(df.format(s.mySqlTimestamp)); + same &= mySqlDate.toString().equals(s.mySqlDate.toString()); + same &= mySqlTime.toString().equals(s.mySqlTime.toString()); + same &= myString.equals(s.myString); + same &= Arrays.equals(myBlob, s.myBlob); + same &= myDefaultFlower.equals(s.myDefaultFlower); + same &= myFavoriteFlower.equals(s.myFavoriteFlower); + same &= myOtherFavoriteFlower.equals(s.myOtherFavoriteFlower); + same &= myFavoriteTree.equals(s.myFavoriteTree); + same &= myOtherFavoriteTree.equals(s.myOtherFavoriteTree); + return same; + } + + /** + * This class demonstrates the table upgrade. + */ + @IQTable(name = "SupportedTypes", inheritColumns = true) + @IQVersion(2) + public static class SupportedTypes2 extends SupportedTypes { + + public SupportedTypes2() { + // nothing to do + } + } +} |