[1710] Add <E> Map<List<?>, List<E>> ResultQuery.fetchGroups(Field<?>[],

Class<E>)
This commit is contained in:
Ivan Dugic 2012-10-08 19:51:23 +02:00
parent 83fe9d9f8f
commit 85488a5cee
6 changed files with 207 additions and 3 deletions

View File

@ -1687,6 +1687,7 @@ extends BaseTest<A, AP, B, S, B2S, BS, L, X, DATE, BOOL, D, T, U, I, IPK, T658,
return;
}
// key -> POJO
// Group by BOOK.ID
Map<Integer, Object> map1 =
create().selectFrom(TBook())
@ -1716,6 +1717,29 @@ extends BaseTest<A, AP, B, S, B2S, BS, L, X, DATE, BOOL, D, T, U, I, IPK, T658,
catch (Throwable t) {
assertEquals(InvalidResultException.class, t.getClass());
}
// keys -> POJO
// Grouping by BOOK.ID, BOOK.LANGUAGE_ID, BOOK.TITLE
Map<List<?>, Object> map4 = create().selectFrom(TBook()).orderBy(TBook_ID())
.fetchMap(new Field<?>[] { TBook_ID(), TBook_LANGUAGE_ID(), TBook_TITLE() }, TBookPojo());
assertEquals(4, map4.keySet().size());
for (List<?> keys : map4.keySet()) {
Object pojo = map4.get(keys);
assertEquals(keys.get(0), on(pojo).call("getId").get());
assertEquals(keys.get(1), on(pojo).call("getLanguageId").get());
assertEquals(keys.get(2), on(pojo).call("getTitle").get());
}
try {
// Grouping by BOOK.AUTHOR_ID
create().selectFrom(TBook()).orderBy(TBook_ID())
.fetchMap(new Field<?>[] { TBook_AUTHOR_ID(), }, TBookPojo());
fail("Fetching map with the non-unique key - InvalidResultException not thrown.");
}
catch (Throwable t) {
assertEquals(InvalidResultException.class, t.getClass());
}
}
@Test
@ -1725,6 +1749,7 @@ extends BaseTest<A, AP, B, S, B2S, BS, L, X, DATE, BOOL, D, T, U, I, IPK, T658,
return;
}
// key -> POJO
// Group by BOOK.ID
Map<Integer, List<Object>> map1 =
create().selectFrom(TBook())
@ -1775,6 +1800,44 @@ extends BaseTest<A, AP, B, S, B2S, BS, L, X, DATE, BOOL, D, T, U, I, IPK, T658,
assertEquals(BOOK_TITLES.get(3), on(entry22.getValue().get(1)).call("getTitle").get());
assertFalse(it.hasNext());
// keys -> POJO
// Grouping by BOOK.AUTHOR_ID, BOOK.LANGUAGE_ID
Map<List<?>, List<Object>> map3 = create().selectFrom(TBook()).orderBy(TBook_ID())
.fetchGroups(new Field<?>[] { TBook_AUTHOR_ID(), TBook_LANGUAGE_ID() }, TBookPojo());
Iterator<Entry<List<?>, List<Object>>> iterator = map3.entrySet().iterator();
Entry<List<?>, List<Object>> entry1_en = iterator.next();
assertEquals(2, entry1_en.getValue().size());
assertEquals(entry1_en.getKey().get(0), on(entry1_en.getValue().get(0)).call("getAuthorId").get());
assertEquals(entry1_en.getKey().get(0), on(entry1_en.getValue().get(1)).call("getAuthorId").get());
assertEquals(entry1_en.getKey().get(1), on(entry1_en.getValue().get(0)).call("getLanguageId").get());
assertEquals(entry1_en.getKey().get(1), on(entry1_en.getValue().get(1)).call("getLanguageId").get());
Entry<List<?>, List<Object>> entry2_pt = iterator.next();
assertEquals(1, entry2_pt.getValue().size());
assertEquals(entry2_pt.getKey().get(0), on(entry2_pt.getValue().get(0)).call("getAuthorId").get());
assertEquals(entry2_pt.getKey().get(1), on(entry2_pt.getValue().get(0)).call("getLanguageId").get());
Entry<List<?>, List<Object>> entry2_de = iterator.next();
assertEquals(1, entry2_de.getValue().size());
assertEquals(entry2_de.getKey().get(0), on(entry2_de.getValue().get(0)).call("getAuthorId").get());
assertEquals(entry2_de.getKey().get(1), on(entry2_de.getValue().get(0)).call("getLanguageId").get());
assertFalse(iterator.hasNext());
// Grouping by BOOK.AUTHOR_ID, BOOK.LANGUAGE_ID, BOOK.TITLE
Map<List<?>, List<Object>> map4 = create().selectFrom(TBook()).orderBy(TBook_ID())
.fetchGroups(new Field<?>[] { TBook_ID(), TBook_LANGUAGE_ID(), TBook_TITLE() }, TBookPojo());
assertEquals(4, map4.size());
for (List<?> keyList : map4.keySet()) {
List<Object> result = map4.get(keyList);
assertEquals(1, result.size());
assertEquals(keyList.get(0), on(result.get(0)).call("getId").get());
assertEquals(keyList.get(1), on(result.get(0)).call("getLanguageId").get());
assertEquals(keyList.get(2), on(result.get(0)).call("getTitle").get());
}
}
@Test

View File

@ -1865,9 +1865,30 @@ public interface Result<R extends Record> extends FieldProvider, List<R>, Attach
* @return A Map containing the result.
* @throws InvalidResultException if the key is non-unique in the result
* set.
* @throws MappingException wrapping any reflection or data type conversion
* exception that might have occurred while mapping records
*/
<K, E> Map<K, E> intoMap(Field<K> key, Class<? extends E> type) throws MappingException;
/**
* Return a {@link Map} with results grouped by the given keys and mapped
* into the given entity type.
* <p>
* An {@link InvalidResultException} is thrown, if the keys are non-unique
* in the result set. Use {@link #intoGroups(Field[], Class)} instead, if
* your keys are non-unique.
*
* @param keys The keys. Client code must assure that keys are unique in the
* result set. If this is <code>null</code> or an empty array,
* the resulting map will contain at most one entry.
* @return A Map containing the results.
* @throws InvalidResultException if the keys are non-unique in the result
* set.
* @throws MappingException wrapping any reflection or data type conversion
* exception that might have occurred while mapping records
*/
<E> Map<List<?>, E> intoMap(Field<?>[] keys, Class<? extends E> type) throws MappingException;
/**
* Return a {@link Map} with one of the result's columns as key and a list
* of corresponding records as value.
@ -1897,8 +1918,7 @@ public interface Result<R extends Record> extends FieldProvider, List<R>, Attach
<K, V> Map<K, List<V>> intoGroups(Field<K> key, Field<V> value);
/**
* Execute the query and return a {@link Map} with the result grouped by the
* given keys.
* Return a {@link Map} with the result grouped by the given keys.
* <p>
* Unlike {@link #intoMap(Field[])}, this method allows for non-unique keys
* in the result set.
@ -1913,7 +1933,6 @@ public interface Result<R extends Record> extends FieldProvider, List<R>, Attach
* Return a {@link Map} with results grouped by the given key and mapped
* into the given entity type.
* <p>
*
* @param <K> The key's generic field type
* @param <E> The generic entity type.
* @param key The key field.
@ -1923,6 +1942,22 @@ public interface Result<R extends Record> extends FieldProvider, List<R>, Attach
*/
<K, E> Map<K, List<E>> intoGroups(Field<K> key, Class<? extends E> type) throws MappingException;
/**
* Return a {@link Map} with results grouped by the given keys and mapped
* into the given entity type.
* <p>
* Unlike {@link #intoMap(Field[], Class)}, this method allows for
* non-unique keys in the result set.
*
* @param keys The keys. If this is <code>null</code> or an empty array, the
* resulting map will contain at most one entry.
* @return A Map containing grouped results
* @throws MappingException wrapping any reflection or data type conversion
* exception that might have occurred while mapping records
*/
<E> Map<List<?>, List<E>> intoGroups(Field<?>[] keys, Class<? extends E> type) throws MappingException;
/**
* Convert this result into an array of arrays
* <p>

View File

@ -519,6 +519,27 @@ public interface ResultQuery<R extends Record> extends Query {
*/
Map<Record, R> fetchMap(Field<?>[] keys) throws DataAccessException;
/**
* Execute the query and return a {@link Map} with results grouped by the
* given keys and mapped into the given entity type.
* <p>
* An {@link InvalidResultException} is thrown, if the keys are non-unique
* in the result set. Use {@link #fetchGroups(Field[], Class)} instead, if
* your keys are non-unique.
*
* @param keys The keys. Client code must assure that keys are unique in the
* result set. If this is <code>null</code> or an empty array,
* the resulting map will contain at most one entry.
* @return A Map containing the results.
* @throws DataAccessException if something went wrong executing the query
* @throws InvalidResultException if the keys are non-unique in the result
* set.
* @throws MappingException wrapping any reflection or data type conversion
* exception that might have occurred while mapping records
* @see Result#intoMap(Field[], Class)
*/
<E> Map<List<?>, E> fetchMap(Field<?>[] keys, Class<? extends E> type) throws MappingException;
/**
* Execute the query and return a {@link Map} with results grouped by the
* given key and mapped into the given entity type.
@ -587,6 +608,23 @@ public interface ResultQuery<R extends Record> extends Query {
*/
Map<Record, Result<R>> fetchGroups(Field<?>[] keys) throws DataAccessException;
/**
* Execute the query and return a {@link Map} with results grouped by the
* given keys and mapped into the given entity type.
* <p>
* Unlike {@link #fetchMap(Field[], Class)}, this method allows for
* non-unique keys in the result set.
*
* @param keys The keys. If this is <code>null</code> or an empty array, the
* resulting map will contain at most one entry.
* @return A Map containing grouped results
* @throws DataAccessException if something went wrong executing the query
* @throws MappingException wrapping any reflection or data type conversion
* exception that might have occurred while mapping records
* @see Result#intoGroups(Field[], Class)
*/
<E> Map<List<?>, List<E>> fetchGroups(Field<?>[] keys, Class<? extends E> type) throws MappingException;
/**
* Return a {@link Map} with results grouped by the given key and mapped
* into the given entity type.

View File

@ -249,6 +249,11 @@ abstract class AbstractDelegatingSelect<R extends Record>
return getDelegate().fetchMap(keys);
}
@Override
public final <E> Map<List<?>, E> fetchMap(Field<?>[] keys, Class<? extends E> type) {
return getDelegate().fetchMap(keys, type);
}
@Override
public final <K, E> Map<K, E> fetchMap(Field<K> key, Class<? extends E> type) {
return getDelegate().fetchMap(key, type);
@ -279,6 +284,11 @@ abstract class AbstractDelegatingSelect<R extends Record>
return getDelegate().fetchGroups(keys);
}
@Override
public final <E> Map<List<?>, List<E>> fetchGroups(Field<?>[] keys, Class<? extends E> type) {
return getDelegate().fetchGroups(keys, type);
}
@Override
public final Object[][] fetchArrays() {
return getDelegate().fetchArrays();

View File

@ -445,6 +445,11 @@ abstract class AbstractResultQuery<R extends Record> extends AbstractQuery imple
return fetch().intoMap(keys);
}
@Override
public final <E> Map<List<?>, E> fetchMap(Field<?>[] keys, Class<? extends E> type) {
return fetch().intoMap(keys, type);
}
@Override
public final <K, E> Map<K, E> fetchMap(Field<K> key, Class<? extends E> type) {
return fetch().intoMap(key, type);
@ -475,6 +480,11 @@ abstract class AbstractResultQuery<R extends Record> extends AbstractQuery imple
return fetch().intoGroups(keys);
}
@Override
public final <E> Map<List<?>, List<E>> fetchGroups(Field<?>[] keys, Class<? extends E> type) {
return fetch().intoGroups(keys, type);
}
@Override
public final Object[][] fetchArrays() {
return fetch().intoArray();

View File

@ -1416,6 +1416,28 @@ class ResultImpl<R extends Record> implements Result<R>, AttachableInternal {
return map;
}
@Override
public final <E> Map<List<?>, E> intoMap(Field<?>[] keys, Class<? extends E> type) {
if (keys == null) {
keys = new Field[0];
}
Map<List<?>, E> map = new LinkedHashMap<List<?>, E>();
for (R record : this) {
List<Object> keyValueList = new ArrayList<Object>();
for (Field<?> key : keys) {
keyValueList.add(record.getValue(key));
}
if (map.put(keyValueList, record.into(type)) != null) {
throw new InvalidResultException("Key list " + keyValueList + " is not unique in Result for " + this);
}
}
return map;
}
@Override
public final <K, E> Map<K, E> intoMap(Field<K> key, Class<? extends E> type) {
Map<K, E> map = new LinkedHashMap<K, E>();
@ -1515,6 +1537,32 @@ class ResultImpl<R extends Record> implements Result<R>, AttachableInternal {
return map;
}
@Override
public final <E> Map<List<?>, List<E>> intoGroups(Field<?>[] keys, Class<? extends E> type) {
if (keys == null) {
keys = new Field[0];
}
Map<List<?>, List<E>> map = new LinkedHashMap<List<?>, List<E>>();
for (R record : this) {
List<Object> keyValueList = new ArrayList<Object>();
for (Field<?> key : keys) {
keyValueList.add(record.getValue(key));
}
List<E> list = map.get(keyValueList);
if (list == null) {
list = new ArrayList<E>();
map.put(keyValueList, list);
}
list.add(record.into(type));
}
return map;
}
@Override
public final Object[][] intoArray() {
int size = size();