diff --git a/jOOQ-test/src/org/jooq/test/_/testcases/FetchTests.java b/jOOQ-test/src/org/jooq/test/_/testcases/FetchTests.java index 5fac14854c..1130a11d82 100644 --- a/jOOQ-test/src/org/jooq/test/_/testcases/FetchTests.java +++ b/jOOQ-test/src/org/jooq/test/_/testcases/FetchTests.java @@ -143,6 +143,19 @@ extends BaseTest(map2.keySet())); assertEquals(BOOK_TITLES, new ArrayList(map2.values())); + // Key list -> Record + // ------------------ + Map, B> map3 = create().selectFrom(TBook()).orderBy(TBook_ID()) + .fetchMap(TBook_ID(), TBook_LANGUAGE_ID(), TBook_TITLE()); + assertEquals(4, map3.keySet().size()); + + for (List keyList : map3.keySet()) { + B record = map3.get(keyList); + assertEquals(keyList.get(0), record.getValue(TBook_ID())); + assertEquals(keyList.get(1), record.getValue(TBook_LANGUAGE_ID())); + assertEquals(keyList.get(2), record.getValue(TBook_TITLE())); + } + // List of Map // ----------- Result books = create().selectFrom(TBook()).orderBy(TBook_ID()).fetch(); @@ -159,10 +172,10 @@ extends BaseTest map3 = create().selectFrom(TBook()).where(TBook_ID().equal(1)).fetchOneMap(); + Map map4 = create().selectFrom(TBook()).where(TBook_ID().equal(1)).fetchOneMap(); for (Field field : books.getFields()) { - assertEquals(book.getValue(field), map3.get(field.getName())); + assertEquals(book.getValue(field), map4.get(field.getName())); } // Maps with two times the same field @@ -237,6 +250,20 @@ extends BaseTest Record + // ---------------------- + Map, Result> map5 = create().selectFrom(TBook()).orderBy(TBook_ID()) + .fetchGroups(TBook_ID(), TBook_LANGUAGE_ID(), TBook_TITLE()); + assertEquals(4, map5.size()); + + for (List keyList : map5.keySet()) { + Result result = map5.get(keyList); + assertEquals(1, result.size()); + assertEquals(keyList.get(0), result.get(0).getValue(TBook_ID())); + assertEquals(keyList.get(1), result.get(0).getValue(TBook_LANGUAGE_ID())); + assertEquals(keyList.get(2), result.get(0).getValue(TBook_TITLE())); + } } @Test diff --git a/jOOQ/src/main/java/org/jooq/Result.java b/jOOQ/src/main/java/org/jooq/Result.java index fc395818c6..db12fc2c82 100644 --- a/jOOQ/src/main/java/org/jooq/Result.java +++ b/jOOQ/src/main/java/org/jooq/Result.java @@ -1835,6 +1835,22 @@ public interface Result extends FieldProvider, List, Attach */ Map intoMap(Field key, Field value); + /** + * Return a {@link Map} with keys list as a map key and the corresponding + * record as value. + *

+ * An {@link InvalidResultException} is thrown, if the key list is + * non-unique in the result set. Use {@link #intoGroups(Field...)} instead, + * if your key list is non-unique. + * + * @param keys The key list. Client code must assure that this key list is + * unique in the result set. + * @return A Map containing the results. + * @throws InvalidResultException if the key list is non-unique in the + * result set. + */ + Map, R> intoMap(Field... keys); + /** * Return a {@link Map} with one of the result's columns as key and a list * of corresponding records as value. @@ -1863,6 +1879,18 @@ public interface Result extends FieldProvider, List, Attach */ Map> intoGroups(Field key, Field value); + /** + * Execute the query and return a {@link Map} with the result grouped by the + * given key list. + *

+ * Unlike {@link #intoMap(Field...)}, this method allows for non-unique key + * list in the result set. + * + * @param keys The key list. + * @return A Map containing grouped results + */ + Map, Result> intoGroups(Field... keys); + /** * Return a {@link Map} with results grouped by the given key and mapped * into the given entity type. diff --git a/jOOQ/src/main/java/org/jooq/ResultQuery.java b/jOOQ/src/main/java/org/jooq/ResultQuery.java index 9a9c121d5c..60bde2f664 100644 --- a/jOOQ/src/main/java/org/jooq/ResultQuery.java +++ b/jOOQ/src/main/java/org/jooq/ResultQuery.java @@ -501,6 +501,24 @@ public interface ResultQuery extends Query { */ Map fetchMap(Field key, Field value) throws DataAccessException; + /** + * Execute the query and return a {@link Map} with keys list as a map key + * and the corresponding record as value. + *

+ * An exception is thrown, if the key list turns out to be non-unique in the + * result set. Use {@link #fetchGroups(Field...)} instead, if your key list + * is non-unique. + * + * @param keys The key list. Client code must assure that this key list is + * unique in the result set. + * @return A Map containing the results. + * @throws DataAccessException if something went wrong executing the query + * @throws InvalidResultException if the key list is non-unique in the + * result set. + * @see Result#intoMap(Field...) + */ + Map, R> fetchMap(Field... keys) throws DataAccessException; + /** * Execute the query and return a {@link Map} with one of the result's * columns as key and a list of corresponding records as value. @@ -537,6 +555,20 @@ public interface ResultQuery extends Query { */ Map> fetchGroups(Field key, Field value) throws DataAccessException; + /** + * Execute the query and return a {@link Map} with the result grouped by the + * given key list. + *

+ * Unlike {@link #fetchMap(Field...)}, this method allows for non-unique key + * list in the result set. + * + * @param keys The key list used for result grouping. + * @return A Map containing grouped results + * @throws DataAccessException if something went wrong executing the query + * @see Result#intoGroups(Field...) + */ + Map, Result> fetchGroups(Field... keys) throws DataAccessException; + /** * Return a {@link Map} with results grouped by the given key and mapped * into the given entity type. diff --git a/jOOQ/src/main/java/org/jooq/impl/AbstractDelegatingSelect.java b/jOOQ/src/main/java/org/jooq/impl/AbstractDelegatingSelect.java index 343c1cef60..f53afa443d 100644 --- a/jOOQ/src/main/java/org/jooq/impl/AbstractDelegatingSelect.java +++ b/jOOQ/src/main/java/org/jooq/impl/AbstractDelegatingSelect.java @@ -233,6 +233,11 @@ abstract class AbstractDelegatingSelect return getDelegate().fetchMap(key, value); } + @Override + public final Map, R> fetchMap(Field... keys) { + return getDelegate().fetchMap(keys); + } + @Override public final List> fetchMaps() { return getDelegate().fetchMaps(); @@ -253,6 +258,11 @@ abstract class AbstractDelegatingSelect return getDelegate().fetchGroups(key, value); } + @Override + public final Map, Result> fetchGroups(Field... keys) { + return getDelegate().fetchGroups(keys); + } + @Override public final Object[][] fetchArrays() { return getDelegate().fetchArrays(); diff --git a/jOOQ/src/main/java/org/jooq/impl/AbstractResultQuery.java b/jOOQ/src/main/java/org/jooq/impl/AbstractResultQuery.java index c1b633728e..64525343c9 100644 --- a/jOOQ/src/main/java/org/jooq/impl/AbstractResultQuery.java +++ b/jOOQ/src/main/java/org/jooq/impl/AbstractResultQuery.java @@ -416,6 +416,11 @@ abstract class AbstractResultQuery extends AbstractQuery imple return fetch().intoMap(key, value); } + @Override + public final Map, R> fetchMap(Field... keys) { + return fetch().intoMap(keys); + } + @Override public final List> fetchMaps() { return fetch().intoMaps(); @@ -436,6 +441,11 @@ abstract class AbstractResultQuery extends AbstractQuery imple return fetch().intoGroups(key, value); } + @Override + public final Map, Result> fetchGroups(Field... keys) { + return fetch().intoGroups(keys); + } + @Override public final Object[][] fetchArrays() { return fetch().intoArray(); diff --git a/jOOQ/src/main/java/org/jooq/impl/ResultImpl.java b/jOOQ/src/main/java/org/jooq/impl/ResultImpl.java index 84182ef52c..14b99b5371 100644 --- a/jOOQ/src/main/java/org/jooq/impl/ResultImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/ResultImpl.java @@ -1400,6 +1400,24 @@ class ResultImpl implements Result, AttachableInternal { return map; } + @Override + public final Map, R> intoMap(Field... keys) { + Map, R> map = new LinkedHashMap, R>(); + + for (R record : this) { + List keyList = new ArrayList(); + for (Field key : keys) { + keyList.add(record.getValue(key)); + } + + if (map.put(keyList, record) != null) { + throw new InvalidResultException("Key list " + keys + " is not unique in Result for " + this); + } + } + + return map; + } + @Override public final Map> intoGroups(Field key) { Map> map = new LinkedHashMap>(); @@ -1439,6 +1457,28 @@ class ResultImpl implements Result, AttachableInternal { return map; } + @Override + public final Map, Result> intoGroups(Field... keys) { + Map, Result> map = new LinkedHashMap, Result>(); + + for (R record : this) { + List keyList = new ArrayList(); + for (Field key : keys) { + keyList.add(record.getValue(key)); + } + + Result result = map.get(keyList); + if (result == null) { + result = new ResultImpl(getConfiguration(), this.fields); + map.put(keyList, result); + } + + result.add(record); + } + + return map; + } + @Override public final Map> intoGroups(Field key, Class type) { Map> map = new LinkedHashMap>();