diff --git a/.classpath b/.classpath
index dc5f793..bc15cad 100644
--- a/.classpath
+++ b/.classpath
@@ -10,5 +10,8 @@
+
+
+
diff --git a/.gitignore b/.gitignore
index 3735cba..4ed9c2c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,4 +3,5 @@ classes/
dist/
docs/
*.class
-*~
\ No newline at end of file
+*~
+docs/
diff --git a/build.xml b/build.xml
index a670095..2fe85a5 100644
--- a/build.xml
+++ b/build.xml
@@ -9,6 +9,7 @@
+
@@ -90,20 +91,20 @@
-
+
-
+
diff --git a/src/java/meetup/beeno/ScanByIndex.java b/src/java/meetup/beeno/ScanByIndex.java
index e6af5b3..2f38830 100644
--- a/src/java/meetup/beeno/ScanByIndex.java
+++ b/src/java/meetup/beeno/ScanByIndex.java
@@ -11,6 +11,7 @@
import meetup.beeno.mapping.EntityInfo;
import meetup.beeno.mapping.IndexMapping;
+import meetup.beeno.mapping.MappingException;
import meetup.beeno.util.HUtil;
import meetup.beeno.util.PBUtil;
@@ -151,9 +152,10 @@ protected ResultScanner getIndexScanner(String tablename,
* for the query.
* @param expressions
* @return
+ * @throws MappingException
*/
protected Criteria.PropertyExpression selectIndexedExpression(EntityInfo info,
- List expressions) {
+ List expressions) throws MappingException {
// first look for a direct match expression
for (Criteria.Expression e : expressions) {
if (e instanceof Criteria.RequireExpression)
@@ -168,8 +170,9 @@ protected Criteria.PropertyExpression selectIndexedExpression(EntityInfo info,
log.warn("No index found for expression property: "+propExpr.getProperty());
}
}
-
- return null;
+ // not property match found
+ // notifying user to avoid returning wrong result set
+ throw new MappingException(info.getClass(), "Can't find property " + expressions);
}
diff --git a/test/java/meetup/beeno/BasicOrmPersistanceTest.java b/test/java/meetup/beeno/BasicOrmPersistanceTest.java
new file mode 100644
index 0000000..13a89c6
--- /dev/null
+++ b/test/java/meetup/beeno/BasicOrmPersistanceTest.java
@@ -0,0 +1,148 @@
+package meetup.beeno;
+
+import static org.junit.Assert.*;
+
+import java.util.List;
+
+import junit.framework.Assert;
+
+import meetup.beeno.Criteria;
+import meetup.beeno.EntityService;
+import meetup.beeno.HBaseException;
+import meetup.beeno.Query;
+import meetup.beeno.mapping.MappingException;
+import meetup.beeno.util.HUtil;
+
+import org.apache.hadoop.hbase.HBaseConfiguration;
+import org.apache.hadoop.hbase.HColumnDescriptor;
+import org.apache.hadoop.hbase.HTableDescriptor;
+import org.apache.hadoop.hbase.TableNotFoundException;
+import org.apache.hadoop.hbase.client.HBaseAdmin;
+import org.apache.hadoop.hbase.client.HTable;
+import org.apache.hadoop.hbase.client.HTablePool;
+import org.apache.hadoop.hbase.util.Bytes;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/*
+ * Commands to create the correspondign hbase schema in HBase Shell
+ * create 'test_simple-by_photoId', '__idx__', 'props'
+ * create 'test_simple', 'props'
+ * Note: This is not required. The test case creates the corresponding tables automatically.
+ */
+
+public class BasicOrmPersistanceTest {
+
+ private static HUtil _hUtil;
+
+ @BeforeClass
+ public static void setUpBeforeClass() throws Exception {
+
+ HBaseConfiguration conf = new HBaseConfiguration();
+ conf.set("hbase.master", "localhost");
+ HTablePool pool = new HTablePool(conf, 10);
+
+ _hUtil = new HUtil();
+ _hUtil.setPool(pool);
+
+ HBaseAdmin admin = new HBaseAdmin(conf);
+
+ // drop tables
+ try {
+ admin.disableTable("test_simple-by_photoId");
+ admin.deleteTable("test_simple-by_photoId");
+ } catch (TableNotFoundException e) {
+ // silently swallow
+ }
+ try {
+ admin.disableTable("test_simple");
+ admin.deleteTable("test_simple");
+ } catch (TableNotFoundException e) {
+ // silently swallow
+ }
+
+ // create tables
+ HTableDescriptor by_photoId_idx = new HTableDescriptor(
+ "test_simple-by_photoId");
+ by_photoId_idx.addFamily(new HColumnDescriptor("__idx__"));
+ by_photoId_idx.addFamily(new HColumnDescriptor("props"));
+ admin.createTable(by_photoId_idx);
+
+ // create tables & index
+ HTableDescriptor test_simple = new HTableDescriptor("test_simple");
+ test_simple.addFamily(new HColumnDescriptor("props"));
+ admin.createTable(test_simple);
+ }
+
+ @AfterClass
+ public static void tearDownAfterClass() throws Exception {
+ }
+
+ @Before
+ public void setUp() throws Exception {
+
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ }
+
+ @Test
+ public void testCreationAndCriteriaRetrieval() throws HBaseException {
+
+ EntityService service = EntityService
+ .create(SimpleEntity.class);
+
+ for (int i = 0; i < 10; i++) {
+ SimpleEntity se = new SimpleEntity();
+ se.setId("r:" + System.currentTimeMillis());
+ se.setStringProperty("superman");
+ se.setDoubleProperty(12.1111D);
+ se.setPhotoIdProperty("PHOTOID" + i);
+ service.save(se);
+ }
+
+ // query rows
+ Query query = service.query().using(Criteria.eq("photoIdProperty", "PHOTOID5"));
+ List items = query.execute();
+ for (SimpleEntity e : items) {
+ System.out.println("items: " + ((SimpleEntity) e).getId());
+ }
+ assertEquals(1, items.size());
+ }
+
+ @Test
+ public void testCreationAndNonExistantCriteriaRetrieval() throws HBaseException {
+
+ EntityService service = EntityService.create(SimpleEntity.class);
+
+ // query rows
+ try{
+ Query query = service.query().using(Criteria.eq("IDONTEXISTFORSURE", "PHOTOID5"));
+ List items = query.execute();
+ fail("Should have gotten a QueryException for the missing properties.");
+ } catch(QueryException e){
+ //Sweet! Got our expected exception.
+ }
+ }
+
+ @Test
+ public void testCreationOfMixedExistingAndNonExistantCriteriaRetrieval() throws HBaseException {
+
+ EntityService service = EntityService.create(SimpleEntity.class);
+
+ // query rows
+ try{
+ Query query = service.query().using(Criteria.eq("IDONTEXISTFORSURE", "PHOTOID5")).where(Criteria.eq("photoIdProperty", "PHOTOID5"));
+ List items = query.execute();
+ fail("Should have gotten a QueryException for the missing properties.");
+ } catch(QueryException e){
+ //Sweet! Got our expected exception.
+ }
+ }
+
+
+}
diff --git a/test/java/meetup/beeno/SimpleEntity.java b/test/java/meetup/beeno/SimpleEntity.java
new file mode 100644
index 0000000..1f279f0
--- /dev/null
+++ b/test/java/meetup/beeno/SimpleEntity.java
@@ -0,0 +1,64 @@
+package meetup.beeno;
+
+import meetup.beeno.HEntity;
+import meetup.beeno.HIndex;
+import meetup.beeno.HProperty;
+import meetup.beeno.HRowKey;
+
+/**
+ * Simple entity class with mapped properties
+ */
+@HEntity(name="test_simple")
+public class SimpleEntity {
+ String id;
+ String stringProperty;
+ int intProperty;
+ float floatProperty;
+ double doubleProperty;
+ long updated = System.currentTimeMillis();
+ String photoId;
+
+ public SimpleEntity() {
+ }
+
+ @HRowKey
+ public String getId() { return this.id; }
+ public void setId(String id) { this.id = id; }
+
+ @HProperty(family="props", name="stringcol")
+ public String getStringProperty() { return stringProperty; }
+ public void setStringProperty( String stringProperty ) {
+ this.stringProperty = stringProperty;
+ }
+
+ @HProperty(family="props", name="photoId", indexes = {@HIndex(date_col="props:updated", date_invert=true)})
+ public String getPhotoIdProperty() { return photoId; }
+ public void setPhotoIdProperty( String photoId ) {
+ this.photoId = photoId;
+ }
+
+ @HProperty(family="props", name="intcol")
+ public int getIntProperty() { return intProperty; }
+ public void setIntProperty( int intProperty ) {
+ this.intProperty = intProperty;
+ }
+
+ @HProperty(family="props", name="floatcol")
+ public float getFloatProperty() { return floatProperty; }
+ public void setFloatProperty( float floatProperty ) {
+ this.floatProperty = floatProperty;
+ }
+
+ @HProperty(family="props", name="doublecol")
+ public double getDoubleProperty() { return doubleProperty; }
+ public void setDoubleProperty( double doubleProperty ) {
+ this.doubleProperty = doubleProperty;
+ }
+
+ @HProperty(family="props", name="updated")
+ public long getUpdated() { return updated; }
+ public void setUpdated( long updateTime ) {
+ this.updated = updateTime;
+ }
+}
+