summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--docs/01_model_classes.mkd12
-rw-r--r--docs/05_releases.mkd6
-rw-r--r--src/com/iciql/Define.java2
-rw-r--r--src/com/iciql/Iciql.java31
-rw-r--r--src/com/iciql/Query.java1
-rw-r--r--src/com/iciql/TableDefinition.java4
-rw-r--r--src/com/iciql/TableInspector.java8
-rw-r--r--src/com/iciql/util/Utils.java16
-rw-r--r--tests/com/iciql/test/BooleanModelTest.java128
-rw-r--r--tests/com/iciql/test/IciqlSuite.java4
-rw-r--r--tests/com/iciql/test/ModelsTest.java2
-rw-r--r--tests/com/iciql/test/models/BooleanModel.java73
-rw-r--r--tests/com/iciql/test/models/Product.java4
-rw-r--r--tests/com/iciql/test/models/ProductAnnotationOnly.java2
-rw-r--r--tests/com/iciql/test/models/ProductMixedAnnotation.java2
-rw-r--r--tests/com/iciql/test/models/SupportedTypes.java10
16 files changed, 266 insertions, 39 deletions
diff --git a/docs/01_model_classes.mkd b/docs/01_model_classes.mkd
index bf8d72c..fb81e0f 100644
--- a/docs/01_model_classes.mkd
+++ b/docs/01_model_classes.mkd
@@ -9,7 +9,7 @@ Alternatively, model classes can be automatically generated by iciql using the m
<table>
<tr><td>java.lang.String</td>
-<td>VARCHAR *(maxLength > 0)* or TEXT *(maxLength == 0)*</td></tr>
+<td>VARCHAR *(length > 0)* or TEXT *(length == 0)*</td></tr>
<tr><td>java.lang.Boolean</td>
<td>BIT</td></tr>
@@ -51,7 +51,7 @@ Alternatively, model classes can be automatically generated by iciql using the m
<td>BLOB</td></tr>
<tr><td>java.lang.Enum.name()</td>
-<td>VARCHAR (maxLength > 0) or TEXT (maxLength == 0)<br/>EnumType.STRING</td></tr>
+<td>VARCHAR (length > 0) or TEXT (length == 0)<br/>EnumType.STRING</td></tr>
<tr><td>java.lang.Enum.ordinal()</td>
<td>INT<br/>EnumType.ORDINAL</td></tr>
@@ -115,10 +115,10 @@ public class Product {
@IQColumn(primaryKey = true)
public Integer productId;
- @IQColumn(maxLength = 200, trimString = true)
+ @IQColumn(length = 200, trim = true)
public String productName;
- @IQColumn(maxLength = 50, trimString = true)
+ @IQColumn(length = 50, trim = true)
public String category;
@IQColumn
@@ -185,8 +185,8 @@ public class Product implements Iciql {
public void defineIQ() {
com.iciql.Define.primaryKey(productId);
com.iciql.Define.columnName(unitsInStock, "units");
- com.iciql.Define.maxLength(productName, 200);
- com.iciql.Define.maxLength(category, 50);
+ com.iciql.Define.length(productName, 200);
+ com.iciql.Define.length(category, 50);
com.iciql.Define.index(productName, category);
}
}
diff --git a/docs/05_releases.mkd b/docs/05_releases.mkd
index 50fda43..d04fbea 100644
--- a/docs/05_releases.mkd
+++ b/docs/05_releases.mkd
@@ -3,9 +3,11 @@
### Current Release
**%VERSION%** ([zip](http://code.google.com/p/iciql/downloads/detail?name=%ZIP%)|[jar](http://code.google.com/p/iciql/downloads/detail?name=%JAR%)) &nbsp; *released %BUILDDATE%*
+- api change release (API v2)
- added BLOB support (issue 1)
- added java.lang.Enum support (issue 2)
-- api change release (API v2)
+- allow runtime flexible mapping of BOOL columns to Integer fields
+- allow runtime flexible mapping of INT columns to Boolean fields
- annotations overhaul to reduce verbosity
- @IQSchema(name="public") -> @IQSchema("public")
- @IQDatabase(version=2) -> @IQVersion(2)
@@ -15,6 +17,8 @@
%BEGINCODE%
@IQIndexes({ @IQIndex("name"), @IQIndex(name="myindexname" value={"name", "nickname"}) })
%ENDCODE%
+ - @IQColumn(maxLength=20) -> @IQColumn(length=20)
+ - @IQColumn(trimString=true) -> @IQColumn(trim=true)
### Older Releases
diff --git a/src/com/iciql/Define.java b/src/com/iciql/Define.java
index 54e435f..d7b42ba 100644
--- a/src/com/iciql/Define.java
+++ b/src/com/iciql/Define.java
@@ -59,7 +59,7 @@ public class Define {
currentTableDefinition.setColumnName(column, columnName);
}
- public static void maxLength(Object column, int length) {
+ public static void length(Object column, int length) {
checkInDefine();
currentTableDefinition.setMaxLength(column, length);
}
diff --git a/src/com/iciql/Iciql.java b/src/com/iciql/Iciql.java
index ff2452e..6abe97d 100644
--- a/src/com/iciql/Iciql.java
+++ b/src/com/iciql/Iciql.java
@@ -37,7 +37,7 @@ import java.lang.annotation.Target;
* <table>
* <tr>
* <td>java.lang.String</td>
- * <td>VARCHAR (maxLength > 0) or TEXT (maxLength == 0)</td>
+ * <td>VARCHAR (length > 0) or TEXT (length == 0)</td>
* </tr>
* <tr>
* <td>java.lang.Boolean</td>
@@ -93,15 +93,19 @@ import java.lang.annotation.Target;
* </tr>
* <tr>
* <td>java.lang.Enum.name()</td>
- * <td>VARCHAR (maxLength > 0) or TEXT (maxLength == 0)<br/>EnumType.STRING</td>
+ * <td>VARCHAR (length > 0) or TEXT (length == 0)<br/>
+ * EnumType.STRING</td>
* </tr>
* <tr>
* <td>java.lang.Enum.ordinal()</td>
- * <td>INT<br/>EnumType.ORDINAL</td>
+ * <td>INT<br/>
+ * EnumType.ORDINAL</td>
* </tr>
* <tr>
- * <td>java.lang.Enum implements<br/>com.iciql.Iciql.EnumID.enumId()</td>
- * <td>INT<br/>EnumType.ENUMID</td>
+ * <td>java.lang.Enum implements<br/>
+ * com.iciql.Iciql.EnumID.enumId()</td>
+ * <td>INT<br/>
+ * EnumType.ENUMID</td>
* </tr>
* </tr>
* </table>
@@ -346,18 +350,18 @@ public interface Iciql {
/**
* If larger than zero, it is used during the CREATE TABLE phase. It may
* also be used to prevent database exceptions on INSERT and UPDATE
- * statements (see trimString).
+ * statements (see trim).
* <p>
- * Any maxLength set in define() may override this annotation setting if
+ * Any length set in define() may override this annotation setting if
* the model class is not annotated with IQTable. Default: 0.
*/
- int maxLength() default 0;
+ int length() default 0;
/**
* If true, iciql will automatically trim the string if it exceeds
- * maxLength (value.substring(0, maxLength)). Default: false.
+ * length (value.substring(0, length)). Default: false.
*/
- boolean trimString() default false;
+ boolean trim() default false;
/**
* If false, iciql will set the column NOT NULL during the CREATE TABLE
@@ -403,7 +407,8 @@ public interface Iciql {
* <li>ORDINAL - ordinal() : int
* <li>ENUMID - enumId() : int
* </ul>
- * @see com.iciql.Iciql.EnumId interface
+ *
+ * @see com.iciql.Iciql.EnumId interface
*/
public enum EnumType {
STRING, ORDINAL, ENUMID;
@@ -428,8 +433,8 @@ public interface Iciql {
* IQEnum(EnumType.STRING)
* </pre>
*
- * A string mapping will generate either a VARCHAR, if IQColumn.maxLength >
- * 0 or a TEXT column if IQColumn.maxLength == 0
+ * A string mapping will generate either a VARCHAR, if IQColumn.length >
+ * 0 or a TEXT column if IQColumn.length == 0
*
*/
@Retention(RetentionPolicy.RUNTIME)
diff --git a/src/com/iciql/Query.java b/src/com/iciql/Query.java
index d9dc84f..0611ffa 100644
--- a/src/com/iciql/Query.java
+++ b/src/com/iciql/Query.java
@@ -222,6 +222,7 @@ public class Query<T> {
try {
X value;
Object o = rs.getObject(1);
+ // Convert CLOB and BLOB now because we close the resultset
if (Clob.class.isAssignableFrom(o.getClass())) {
value = (X) Utils.convert(o, String.class);
} else if (Blob.class.isAssignableFrom(o.getClass())) {
diff --git a/src/com/iciql/TableDefinition.java b/src/com/iciql/TableDefinition.java
index 72b5348..5d9b9c4 100644
--- a/src/com/iciql/TableDefinition.java
+++ b/src/com/iciql/TableDefinition.java
@@ -285,8 +285,8 @@ class TableDefinition<T> {
}
isAutoIncrement = col.autoIncrement();
isPrimaryKey = col.primaryKey();
- maxLength = col.maxLength();
- trimString = col.trimString();
+ maxLength = col.length();
+ trimString = col.trim();
allowNull = col.allowNull();
defaultValue = col.defaultValue();
}
diff --git a/src/com/iciql/TableInspector.java b/src/com/iciql/TableInspector.java
index 879e23a..82b732a 100644
--- a/src/com/iciql/TableInspector.java
+++ b/src/com/iciql/TableInspector.java
@@ -346,13 +346,13 @@ public class TableInspector {
ap.addParameter("primaryKey=true");
}
- // IQColumn.maxLength
+ // IQColumn.length
if ((clazz == String.class) && (col.size > 0) && (col.size < Integer.MAX_VALUE)) {
- ap.addParameter("maxLength", col.size);
+ ap.addParameter("length", col.size);
- // IQColumn.trimStrings
+ // IQColumn.trim
if (trimStrings) {
- ap.addParameter("trimString=true");
+ ap.addParameter("trim=true");
}
} else {
// IQColumn.AutoIncrement
diff --git a/src/com/iciql/util/Utils.java b/src/com/iciql/util/Utils.java
index 302dd4d..dac30fc 100644
--- a/src/com/iciql/util/Utils.java
+++ b/src/com/iciql/util/Utils.java
@@ -226,6 +226,22 @@ public class Utils {
return o.toString();
}
+ // convert from number to boolean
+ if (Boolean.class.isAssignableFrom(targetType)) {
+ if (Number.class.isAssignableFrom(currentType)) {
+ Number n = (Number) o;
+ return n.intValue() > 0;
+ }
+ }
+
+ // convert from boolean to number
+ if (Boolean.class.isAssignableFrom(currentType)) {
+ if (Number.class.isAssignableFrom(targetType)) {
+ Boolean b = (Boolean) o;
+ return b ? 1 : 0;
+ }
+ }
+
// convert from number to number
if (Number.class.isAssignableFrom(currentType)) {
Number n = (Number) o;
diff --git a/tests/com/iciql/test/BooleanModelTest.java b/tests/com/iciql/test/BooleanModelTest.java
new file mode 100644
index 0000000..0287e06
--- /dev/null
+++ b/tests/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 = Db.open("jdbc:h2:mem:", "sa", "sa");
+ 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 = Db.open("jdbc:h2:mem:", "sa", "sa");
+ // 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/tests/com/iciql/test/IciqlSuite.java b/tests/com/iciql/test/IciqlSuite.java
index b235f6d..20dbea2 100644
--- a/tests/com/iciql/test/IciqlSuite.java
+++ b/tests/com/iciql/test/IciqlSuite.java
@@ -25,8 +25,8 @@ import org.junit.runners.Suite.SuiteClasses;
*
*/
@RunWith(Suite.class)
-@SuiteClasses({ AliasMapTest.class, AnnotationsTest.class, ClobTest.class, ConcurrencyTest.class,
- ModelsTest.class, SamplesTest.class, UpdateTest.class, RuntimeQueryTest.class,
+@SuiteClasses({ AliasMapTest.class, AnnotationsTest.class, BooleanModelTest.class, ClobTest.class,
+ ConcurrencyTest.class, ModelsTest.class, SamplesTest.class, UpdateTest.class, RuntimeQueryTest.class,
StatementLoggerTest.class })
public class IciqlSuite {
diff --git a/tests/com/iciql/test/ModelsTest.java b/tests/com/iciql/test/ModelsTest.java
index 716b1bc..9012296 100644
--- a/tests/com/iciql/test/ModelsTest.java
+++ b/tests/com/iciql/test/ModelsTest.java
@@ -115,7 +115,7 @@ public class ModelsTest {
true);
assertEquals(1, models.size());
// a poor test, but a start
- assertEquals(1904, models.get(0).length());
+ assertEquals(1895, models.get(0).length());
}
@Test
diff --git a/tests/com/iciql/test/models/BooleanModel.java b/tests/com/iciql/test/models/BooleanModel.java
new file mode 100644
index 0000000..d22e3c1
--- /dev/null
+++ b/tests/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/tests/com/iciql/test/models/Product.java b/tests/com/iciql/test/models/Product.java
index 735ebab..065e624 100644
--- a/tests/com/iciql/test/models/Product.java
+++ b/tests/com/iciql/test/models/Product.java
@@ -18,7 +18,7 @@
package com.iciql.test.models;
import static com.iciql.Define.index;
-import static com.iciql.Define.maxLength;
+import static com.iciql.Define.length;
import static com.iciql.Define.primaryKey;
import static com.iciql.Define.tableName;
@@ -54,7 +54,7 @@ public class Product implements Iciql {
public void defineIQ() {
tableName("Product");
primaryKey(productId);
- maxLength(category, 255);
+ length(category, 255);
index(productName, category);
}
diff --git a/tests/com/iciql/test/models/ProductAnnotationOnly.java b/tests/com/iciql/test/models/ProductAnnotationOnly.java
index caf07c7..673ca14 100644
--- a/tests/com/iciql/test/models/ProductAnnotationOnly.java
+++ b/tests/com/iciql/test/models/ProductAnnotationOnly.java
@@ -42,7 +42,7 @@ public class ProductAnnotationOnly {
@IQColumn(name = "id")
public Integer productId;
- @IQColumn(name = "cat", maxLength = 15, trimString = true)
+ @IQColumn(name = "cat", length = 15, trim = true)
public String category;
@IQColumn(name = "name")
diff --git a/tests/com/iciql/test/models/ProductMixedAnnotation.java b/tests/com/iciql/test/models/ProductMixedAnnotation.java
index 1d3cb8f..ff7d46f 100644
--- a/tests/com/iciql/test/models/ProductMixedAnnotation.java
+++ b/tests/com/iciql/test/models/ProductMixedAnnotation.java
@@ -36,7 +36,7 @@ public class ProductMixedAnnotation {
public Integer unitsInStock;
public String mappedField;
- @IQColumn(name = "cat", maxLength = 255)
+ @IQColumn(name = "cat", length = 255)
public String category;
@IQColumn(name = "id", primaryKey = true)
diff --git a/tests/com/iciql/test/models/SupportedTypes.java b/tests/com/iciql/test/models/SupportedTypes.java
index 97a8675..c8aebcb 100644
--- a/tests/com/iciql/test/models/SupportedTypes.java
+++ b/tests/com/iciql/test/models/SupportedTypes.java
@@ -80,10 +80,10 @@ public class SupportedTypes {
public Integer id;
@IQColumn
- private Boolean myBool = false;
+ private Boolean myBool;
@IQColumn
- private Byte myByte = 2;
+ private Byte myByte;
@IQColumn
private Short myShort;
@@ -95,7 +95,7 @@ public class SupportedTypes {
private Long myLong;
@IQColumn
- private Float myFloat = 1.0f;
+ private Float myFloat;
@IQColumn
private Double myDouble;
@@ -122,14 +122,14 @@ public class SupportedTypes {
private byte[] myBlob;
@IQEnum(EnumType.STRING)
- @IQColumn(trimString = true, maxLength = 25)
+ @IQColumn(trim = true, length = 25)
private Flower myFavoriteFlower;
@IQEnum(EnumType.ORDINAL)
@IQColumn
private Flower myOtherFavoriteFlower;
- @IQColumn(maxLength = 25)
+ @IQColumn(length = 25)
// @IQEnum is set on the enumeration definition and is shared
// by all uses of Tree as an @IQColumn
private Tree myFavoriteTree;