Repository: cayenne
Updated Branches:
  refs/heads/master 16e5513cd -> 047a29477


CAY-1959 Chainable API for SelectQuery

* 'selectFirst' method


Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo
Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/047a2947
Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/047a2947
Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/047a2947

Branch: refs/heads/master
Commit: 047a29477202b145b9f14e0bd7aea312500a6e10
Parents: 16e5513
Author: aadamchik <[email protected]>
Authored: Sat Nov 22 14:09:26 2014 +0300
Committer: aadamchik <[email protected]>
Committed: Fri Nov 28 16:58:38 2014 +0300

----------------------------------------------------------------------
 .../org/apache/cayenne/query/ObjectSelect.java  | 25 +++++++-
 .../org/apache/cayenne/query/SQLSelect.java     | 25 +++++++-
 .../org/apache/cayenne/query/SelectById.java    |  9 ++-
 .../cayenne/query/ObjectSelect_RunIT.java       | 61 +++++++++++++++++---
 4 files changed, 107 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cayenne/blob/047a2947/cayenne-server/src/main/java/org/apache/cayenne/query/ObjectSelect.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/query/ObjectSelect.java 
b/cayenne-server/src/main/java/org/apache/cayenne/query/ObjectSelect.java
index b6395dc..022bcf6 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/query/ObjectSelect.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/query/ObjectSelect.java
@@ -661,11 +661,32 @@ public class ObjectSelect<T> extends IndirectQuery 
implements Select<T> {
        }
 
        /**
-        * Selects a single object using provided context. Essentially the 
inversion
-        * of "ObjectContext.selectOne(Select)".
+        * Selects a single object using provided context. The query is 
expected to
+        * match zero or one object. It returns null if no objects were 
matched. If
+        * query matched more than one object, {@link CayenneRuntimeException} 
is
+        * thrown.
+        * <p>
+        * Essentially the inversion of "ObjectContext.selectOne(Select)".
         */
        public T selectOne(ObjectContext context) {
                return context.selectOne(this);
        }
 
+       /**
+        * Selects a single object using provided context. The query itself can
+        * match any number of objects, but will return only the first one. It
+        * returns null if no objects were matched.
+        * <p>
+        * If it matched more than one object, the first object from the list is
+        * returned. This makes 'selectFirst' different from
+        * {@link #selectOne(ObjectContext)}, which would throw in this 
situation.
+        * 'selectFirst' is useful e.g. when the query is ordered and we only 
want
+        * to see the first object (e.g. "most recent news article"), etc.
+        * <p>
+        * This method is equivalent to calling "limit(1).selectOne(context)".
+        */
+       public T selectFirst(ObjectContext context) {
+               return limit(1).selectOne(context);
+       }
+
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/047a2947/cayenne-server/src/main/java/org/apache/cayenne/query/SQLSelect.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/query/SQLSelect.java 
b/cayenne-server/src/main/java/org/apache/cayenne/query/SQLSelect.java
index b4504f4..ebd5d58 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/query/SQLSelect.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/query/SQLSelect.java
@@ -121,13 +121,34 @@ public class SQLSelect<T> extends IndirectQuery 
implements Select<T> {
        }
 
        /**
-        * Selects a single object using provided context. Essentially the 
inversion
-        * of "ObjectContext.selectOne(Select)".
+        * Selects a single object using provided context. The query is 
expected to
+        * match zero or one object. It returns null if no objects were 
matched. If
+        * query matched more than one object, {@link CayenneRuntimeException} 
is
+        * thrown.
+        * <p>
+        * Essentially the inversion of "ObjectContext.selectOne(Select)".
         */
        public T selectOne(ObjectContext context) {
                return context.selectOne(this);
        }
 
+       /**
+        * Selects a single object using provided context. The query itself can
+        * match any number of objects, but will return only the first one. It
+        * returns null if no objects were matched.
+        * <p>
+        * If it matched more than one object, the first object from the list is
+        * returned. This makes 'selectFirst' different from
+        * {@link #selectOne(ObjectContext)}, which would throw in this 
situation.
+        * 'selectFirst' is useful e.g. when the query is ordered and we only 
want
+        * to see the first object (e.g. "most recent news article"), etc.
+        * <p>
+        * This method is equivalent to calling "limit(1).selectOne(context)".
+        */
+       public T selectFirst(ObjectContext context) {
+               return limit(1).selectOne(context);
+       }
+
        public boolean isFetchingDataRows() {
                return persistentType == null;
        }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/047a2947/cayenne-server/src/main/java/org/apache/cayenne/query/SelectById.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/query/SelectById.java 
b/cayenne-server/src/main/java/org/apache/cayenne/query/SelectById.java
index bec8c75..00ee205 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/query/SelectById.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/query/SelectById.java
@@ -125,8 +125,13 @@ public class SelectById<T> extends IndirectQuery 
implements Select<T> {
        }
 
        /**
-        * Selects a single object using provided context. Essentially the 
inversion
-        * of "ObjectContext.selectOne(Select)".
+        * Selects a single object using provided context. The query is 
expected to
+        * match zero or one object. It returns null if no objects were 
matched. If
+        * query matched more than one object, {@link CayenneRuntimeException} 
is
+        * thrown. Since we are selecting by ID, multiple matched objects likely
+        * indicate a database referential integrity problem.
+        * <p>
+        * Essentially the inversion of "ObjectContext.selectOne(Select)".
         */
        public T selectOne(ObjectContext context) {
                return context.selectOne(this);

http://git-wip-us.apache.org/repos/asf/cayenne/blob/047a2947/cayenne-server/src/test/java/org/apache/cayenne/query/ObjectSelect_RunIT.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/test/java/org/apache/cayenne/query/ObjectSelect_RunIT.java 
b/cayenne-server/src/test/java/org/apache/cayenne/query/ObjectSelect_RunIT.java
index 194b94b..17e128b 100644
--- 
a/cayenne-server/src/test/java/org/apache/cayenne/query/ObjectSelect_RunIT.java
+++ 
b/cayenne-server/src/test/java/org/apache/cayenne/query/ObjectSelect_RunIT.java
@@ -18,6 +18,15 @@
  ****************************************************************/
 package org.apache.cayenne.query;
 
+import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertThat;
+
+import java.util.List;
+
+import org.apache.cayenne.CayenneRuntimeException;
 import org.apache.cayenne.DataRow;
 import org.apache.cayenne.access.DataContext;
 import org.apache.cayenne.di.Inject;
@@ -29,13 +38,6 @@ import org.apache.cayenne.unit.di.server.ServerCase;
 import org.apache.cayenne.unit.di.server.UseServerRuntime;
 import org.junit.Test;
 
-import java.util.List;
-
-import static org.hamcrest.CoreMatchers.instanceOf;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertThat;
-
 @UseServerRuntime(CayenneProjects.TESTMAP_PROJECT)
 public class ObjectSelect_RunIT extends ServerCase {
 
@@ -83,4 +85,49 @@ public class ObjectSelect_RunIT extends ServerCase {
                assertNotNull(a);
                assertEquals("artist14", a.get("ARTIST_NAME"));
        }
+
+       @Test
+       public void test_SelectOne() throws Exception {
+               createArtistsDataSet();
+
+               Artist a = 
ObjectSelect.query(Artist.class).where(Artist.ARTIST_NAME.eq("artist13")).selectOne(context);
+               assertNotNull(a);
+               assertEquals("artist13", a.getArtistName());
+       }
+
+       @Test
+       public void test_SelectOne_NoMatch() throws Exception {
+               Artist a = 
ObjectSelect.query(Artist.class).where(Artist.ARTIST_NAME.eq("artist13")).selectOne(context);
+               assertNull(a);
+       }
+
+       @Test(expected = CayenneRuntimeException.class)
+       public void test_SelectOne_MoreThanOneMatch() throws Exception {
+               createArtistsDataSet();
+               
ObjectSelect.query(Artist.class).where(Artist.ARTIST_NAME.like("artist%")).selectOne(context);
+       }
+       
+       @Test
+       public void test_SelectFirst() throws Exception {
+               createArtistsDataSet();
+
+               Artist a = 
ObjectSelect.query(Artist.class).where(Artist.ARTIST_NAME.eq("artist13")).selectFirst(context);
+               assertNotNull(a);
+               assertEquals("artist13", a.getArtistName());
+       }
+
+       @Test
+       public void test_SelectFirst_NoMatch() throws Exception {
+               Artist a = 
ObjectSelect.query(Artist.class).where(Artist.ARTIST_NAME.eq("artist13")).selectFirst(context);
+               assertNull(a);
+       }
+
+       @Test
+       public void test_SelectFirst_MoreThanOneMatch() throws Exception {
+               createArtistsDataSet();
+               
+               Artist a = 
ObjectSelect.query(Artist.class).where(Artist.ARTIST_NAME.like("artist%")).orderBy("db:ARTIST_ID").selectFirst(context);
+               assertNotNull(a);
+               assertEquals("artist1", a.getArtistName());
+       }
 }

Reply via email to