cayenne-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From skolbac...@apache.org
Subject cayenne git commit: CAY-1995 | Add selectFirst() to Select and ObjectContext
Date Fri, 03 Apr 2015 15:28:42 GMT
Repository: cayenne
Updated Branches:
  refs/heads/master c38a8e6b8 -> 44fdc8454


CAY-1995 | Add selectFirst() to Select and ObjectContext


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

Branch: refs/heads/master
Commit: 44fdc8454b949d665e1b79068e0f31d4967c8d6f
Parents: c38a8e6
Author: Savva Kolbachev <s.kolbachev@gmail.com>
Authored: Fri Apr 3 18:27:42 2015 +0300
Committer: Savva Kolbachev <s.kolbachev@gmail.com>
Committed: Fri Apr 3 18:27:42 2015 +0300

----------------------------------------------------------------------
 .../java/org/apache/cayenne/BaseContext.java    | 24 ++++++++++++++------
 .../java/org/apache/cayenne/ObjectContext.java  | 19 ++++++++++++++++
 .../org/apache/cayenne/query/ObjectSelect.java  | 22 ++++--------------
 .../org/apache/cayenne/query/SQLSelect.java     | 22 ++++--------------
 .../java/org/apache/cayenne/query/Select.java   | 24 ++++++++++++++++++++
 .../org/apache/cayenne/query/SelectById.java    |  9 ++++++++
 .../org/apache/cayenne/query/SelectQuery.java   |  6 +++++
 .../cayenne/remote/IncrementalSelectQuery.java  |  5 ++++
 .../cayenne/query/ObjectSelect_RunIT.java       | 10 ++++++++
 .../org/apache/cayenne/query/SQLSelectIT.java   | 21 +++++++++++++++++
 .../org/apache/cayenne/query/SelectQueryIT.java | 24 ++++++++++++++++++++
 11 files changed, 145 insertions(+), 41 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cayenne/blob/44fdc845/cayenne-server/src/main/java/org/apache/cayenne/BaseContext.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/BaseContext.java b/cayenne-server/src/main/java/org/apache/cayenne/BaseContext.java
index dd61318..45881c9 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/BaseContext.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/BaseContext.java
@@ -18,13 +18,6 @@
  ****************************************************************/
 package org.apache.cayenne;
 
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
 import org.apache.cayenne.cache.NestedQueryCache;
 import org.apache.cayenne.cache.QueryCache;
 import org.apache.cayenne.configuration.CayenneRuntime;
@@ -50,6 +43,13 @@ import org.apache.cayenne.reflect.ToManyProperty;
 import org.apache.cayenne.reflect.ToOneProperty;
 import org.apache.cayenne.util.ObjectContextGraphAction;
 
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
 /**
  * A common base superclass for Cayenne ObjectContext implementors.
  * 
@@ -327,6 +327,16 @@ public abstract class BaseContext implements ObjectContext {
      * @since 4.0
      */
     @Override
+    public <T> T selectFirst(Select<T> query) {
+        List<T> objects = select(query);
+
+        return (objects == null || objects.isEmpty()) ? null : objects.get(0);
+    }
+
+    /**
+     * @since 4.0
+     */
+    @Override
     public <T> void iterate(Select<T> query, ResultIteratorCallback<T>
callback) {
         ResultIterator<T> it = iterator(query);
         try {

http://git-wip-us.apache.org/repos/asf/cayenne/blob/44fdc845/cayenne-server/src/main/java/org/apache/cayenne/ObjectContext.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/ObjectContext.java b/cayenne-server/src/main/java/org/apache/cayenne/ObjectContext.java
index 5efb19a..8f0c1dd 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/ObjectContext.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/ObjectContext.java
@@ -194,6 +194,25 @@ public interface ObjectContext extends DataChannel, Serializable {
     <T> T selectOne(Select<T> query);
 
     /**
+     * Selects a single object using provided query. 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(Select)}, 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>
+     * Selecting the first object via "Select.selectFirst(ObjectContext)"
+     * is more comprehensible than selecting via "ObjectContext.selectFirst(Select)",
+     * because implementations of "Select" set fetch size limit to one.
+     *
+     * @since 4.0
+     */
+    <T> T selectFirst(Select<T> query);
+
+    /**
      * Creates a ResultIterator based on the provided query and passes it to a
      * callback for processing. The caller does not need to worry about closing
      * the iterator. This method takes care of it.

http://git-wip-us.apache.org/repos/asf/cayenne/blob/44fdc845/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 1c9f53b..5d7172d 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
@@ -665,6 +665,11 @@ public class ObjectSelect<T> extends IndirectQuery implements Select<T>
{
 	}
 
     @Override
+    public T selectFirst(ObjectContext context) {
+        return context.selectFirst(limit(1));
+    }
+
+    @Override
     public <T> void iterate(ObjectContext context, ResultIteratorCallback<T>
callback) {
         context.iterate((Select<T>) this, callback);
     }
@@ -674,21 +679,4 @@ public class ObjectSelect<T> extends IndirectQuery implements Select<T>
{
         return context.iterator(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/44fdc845/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 2a51081..e93fc50 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
@@ -125,6 +125,11 @@ public class SQLSelect<T> extends IndirectQuery implements Select<T>
{
 	}
 
     @Override
+    public T selectFirst(ObjectContext context) {
+        return context.selectFirst(limit(1));
+    }
+
+    @Override
     public <T> void iterate(ObjectContext context, ResultIteratorCallback<T>
callback) {
         context.iterate((Select<T>) this, callback);
     }
@@ -134,23 +139,6 @@ public class SQLSelect<T> extends IndirectQuery implements Select<T>
{
         return context.iterator(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/44fdc845/cayenne-server/src/main/java/org/apache/cayenne/query/Select.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/query/Select.java b/cayenne-server/src/main/java/org/apache/cayenne/query/Select.java
index 4cfe9f3..f744d5c 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/query/Select.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/query/Select.java
@@ -35,6 +35,7 @@ public interface Select<T> extends Query {
      * Selects objects using provided context.
      * <p>
      * Essentially the inversion of "ObjectContext.select(Select)".
+     *
      * @since 4.0
      */
     <T> List<T> select(ObjectContext context);
@@ -46,15 +47,37 @@ public interface Select<T> extends Query {
      * thrown.
      * <p>
      * Essentially the inversion of "ObjectContext.selectOne(Select)".
+     *
+     * @since 4.0
      */
     <T> T selectOne(ObjectContext context);
 
     /**
+     * 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>
+     * Selecting the first object via "Select.selectFirst(ObjectContext)"
+     * is more comprehensible than selecting via "ObjectContext.selectFirst(Select)",
+     * because implementations of "Select" set fetch size limit to one.
+     *
+     * @since 4.0
+     */
+    <T> T selectFirst(ObjectContext context);
+
+    /**
      * Creates a ResultIterator based on the provided context and passes it to a
      * callback for processing. The caller does not need to worry about closing
      * the iterator. This method takes care of it.
      * <p>
      * Essentially the inversion of "ObjectContext.iterate(Select, ResultIteratorCallback)".
+     *
      * @since 4.0
      */
     <T> void iterate(ObjectContext context, ResultIteratorCallback<T> callback);
@@ -68,6 +91,7 @@ public interface Select<T> extends Query {
      * Or use {@link #iterate(ObjectContext, ResultIteratorCallback)} as an alternative.
      * <p>
      * Essentially the inversion of "ObjectContext.iterator(Select)".
+     *
      * @since 4.0
      */
     <T> ResultIterator<T> iterator(ObjectContext context);

http://git-wip-us.apache.org/repos/asf/cayenne/blob/44fdc845/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 4c3187f..50c0750 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
@@ -143,6 +143,15 @@ public class SelectById<T> extends IndirectQuery implements Select<T>
{
 		return context.selectOne(this);
 	}
 
+    /**
+     * Since we are selecting by ID, we don't need to limit fetch size.
+     * Multiple matched objects likely indicate a database referential integrity problem.
+     */
+    @Override
+    public T selectFirst(ObjectContext context) {
+        return selectFirst(context);
+    }
+
     @Override
     public <T> void iterate(ObjectContext context, ResultIteratorCallback<T>
callback) {
         context.iterate((Select<T>) this, callback);

http://git-wip-us.apache.org/repos/asf/cayenne/blob/44fdc845/cayenne-server/src/main/java/org/apache/cayenne/query/SelectQuery.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/query/SelectQuery.java b/cayenne-server/src/main/java/org/apache/cayenne/query/SelectQuery.java
index fd446b8..f116af7 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/query/SelectQuery.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/query/SelectQuery.java
@@ -318,6 +318,12 @@ public class SelectQuery<T> extends AbstractQuery implements ParameterizedQuery,
     }
 
     @Override
+    public T selectFirst(ObjectContext context) {
+        setFetchLimit(1);
+        return context.selectFirst(this);
+    }
+
+    @Override
     public <T> void iterate(ObjectContext context, ResultIteratorCallback<T>
callback) {
         context.iterate((Select<T>) this, callback);
     }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/44fdc845/cayenne-server/src/main/java/org/apache/cayenne/remote/IncrementalSelectQuery.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/remote/IncrementalSelectQuery.java
b/cayenne-server/src/main/java/org/apache/cayenne/remote/IncrementalSelectQuery.java
index 451885c..a1cd059 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/remote/IncrementalSelectQuery.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/remote/IncrementalSelectQuery.java
@@ -355,6 +355,11 @@ class IncrementalSelectQuery<T> extends SelectQuery<T> {
     }
 
     @Override
+    public T selectFirst(ObjectContext context) {
+        return query.selectFirst(context);
+    }
+
+    @Override
     public <T> void iterate(ObjectContext context, ResultIteratorCallback<T>
callback) {
         query.iterate(context, callback);
     }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/44fdc845/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 8c018aa..8cd551d 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
@@ -154,6 +154,16 @@ public class ObjectSelect_RunIT extends ServerCase {
 		assertEquals("artist13", a.getArtistName());
 	}
 
+    @Test
+    public void test_SelectFirstByContext() throws Exception {
+        createArtistsDataSet();
+
+        ObjectSelect<Artist> q = ObjectSelect.query(Artist.class).where(Artist.ARTIST_NAME.eq("artist13"));
+        Artist a = context.selectFirst(q);
+        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);

http://git-wip-us.apache.org/repos/asf/cayenne/blob/44fdc845/cayenne-server/src/test/java/org/apache/cayenne/query/SQLSelectIT.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/query/SQLSelectIT.java b/cayenne-server/src/test/java/org/apache/cayenne/query/SQLSelectIT.java
index 8a5f209..0061a84 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/query/SQLSelectIT.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/query/SQLSelectIT.java
@@ -202,6 +202,27 @@ public class SQLSelectIT extends ServerCase {
 	}
 
     @Test
+    public void test_SelectFirst() throws Exception {
+        createPaintingsDataSet();
+
+        Painting p = SQLSelect.query(Painting.class, "SELECT * FROM PAINTING ORDER BY PAINTING_TITLE").selectFirst(context);
+
+        assertNotNull(p);
+        assertEquals("painting1", p.getPaintingTitle());
+    }
+
+    @Test
+    public void test_SelectFirstByContext() throws Exception {
+        createPaintingsDataSet();
+
+        SQLSelect<Painting> q = SQLSelect.query(Painting.class, "SELECT * FROM PAINTING
ORDER BY PAINTING_TITLE");
+        Painting p = context.selectFirst(q);
+
+        assertNotNull(p);
+        assertEquals("painting1", p.getPaintingTitle());
+    }
+
+    @Test
     public void test_Iterate() throws Exception {
         createPaintingsDataSet();
 

http://git-wip-us.apache.org/repos/asf/cayenne/blob/44fdc845/cayenne-server/src/test/java/org/apache/cayenne/query/SelectQueryIT.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/query/SelectQueryIT.java b/cayenne-server/src/test/java/org/apache/cayenne/query/SelectQueryIT.java
index cf532f4..785e1a7 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/query/SelectQueryIT.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/query/SelectQueryIT.java
@@ -512,6 +512,30 @@ public class SelectQueryIT extends ServerCase {
     }
 
     @Test
+    public void testSelectFirst() throws Exception {
+        createArtistsDataSet();
+
+        SelectQuery query = new SelectQuery(Artist.class);
+        query.addOrdering(new Ordering(Artist.ARTIST_NAME.getName()));
+        Artist artist = (Artist) query.selectFirst(context);
+
+        assertNotNull(artist);
+        assertEquals("artist1", artist.getArtistName());
+    }
+
+    @Test
+    public void testSelectFirstByContext() throws Exception {
+        createArtistsDataSet();
+
+        SelectQuery query = new SelectQuery(Artist.class);
+        query.addOrdering(new Ordering(Artist.ARTIST_NAME.getName()));
+        Artist artist = (Artist) context.selectFirst(query);
+
+        assertNotNull(artist);
+        assertEquals("artist1", artist.getArtistName());
+    }
+
+    @Test
     public void testIterate() throws Exception {
         createArtistsDataSet();
 


Mime
View raw message