[#3626] Add Map<S, Result<R>> Result.intoGroups(Table<S>)

This commit is contained in:
Lukas Eder 2014-09-08 11:38:45 +02:00
parent 0877a37084
commit 727327447b
5 changed files with 437 additions and 65 deletions

View File

@ -673,25 +673,6 @@ public interface Result<R extends Record> extends List<R>, Attachable {
*/
<K, V> Map<K, V> intoMap(Field<K> key, Field<V> value) throws IllegalArgumentException, InvalidResultException;
/**
* Return a {@link Map} with the given keys as a map key and the
* corresponding record as value.
* <p>
* An {@link InvalidResultException} is thrown, if the keys are non-unique
* in the result set. Use {@link #intoGroups(Field[])} 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 IllegalArgumentException If any of the argument fields is not
* contained in {@link #fieldsRow()}
* @throws InvalidResultException if the keys are non-unique in the result
* set.
*/
Map<Record, R> intoMap(Field<?>[] keys) throws IllegalArgumentException, InvalidResultException;
/**
* Return a {@link Map} with results grouped by the given key and mapped
* into the given entity type.
@ -738,6 +719,25 @@ public interface Result<R extends Record> extends List<R>, Attachable {
<K, E> Map<K, E> intoMap(Field<K> key, RecordMapper<? super R, E> mapper) throws IllegalArgumentException,
InvalidResultException, MappingException;
/**
* Return a {@link Map} with the given keys as a map key and the
* corresponding record as value.
* <p>
* An {@link InvalidResultException} is thrown, if the keys are non-unique
* in the result set. Use {@link #intoGroups(Field[])} 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 IllegalArgumentException If any of the argument fields is not
* contained in {@link #fieldsRow()}
* @throws InvalidResultException if the keys are non-unique in the result
* set.
*/
Map<Record, R> intoMap(Field<?>[] keys) throws IllegalArgumentException, InvalidResultException;
/**
* Return a {@link Map} with results grouped by the given keys and mapped
* into the given entity type.
@ -785,6 +785,70 @@ public interface Result<R extends Record> extends List<R>, Attachable {
<E> Map<List<?>, E> intoMap(Field<?>[] keys, RecordMapper<? super R, E> mapper) throws IllegalArgumentException,
InvalidResultException, MappingException;
/**
* Return a {@link Map} with the given key table as a map key and the
* corresponding record as value.
* <p>
* An {@link InvalidResultException} is thrown, if the keys are non-unique
* in the result set. Use {@link #intoGroups(Table)} instead, if your keys
* are non-unique.
*
* @param table The key table. Client code must assure that keys are unique
* in the result set. May not be <code>null</code>.
* @return A Map containing the results.
* @throws IllegalArgumentException If any of the argument fields is not
* contained in {@link #fieldsRow()}
* @throws InvalidResultException if the keys are non-unique in the result
* set.
*/
<S extends Record> Map<S, R> intoMap(Table<S> table) throws IllegalArgumentException, InvalidResultException;
/**
* Return a {@link Map} with results grouped by the given key table 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(Table, Class)} instead, if your
* keys are non-unique.
*
* @param table The key table. Client code must assure that keys are unique
* in the result set. May not be <code>null</code>.
* @param type The entity type.
* @return A Map containing the results.
* @throws IllegalArgumentException If any of the argument fields is not
* contained in {@link #fieldsRow()}
* @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 DefaultRecordMapper
*/
<E, S extends Record> Map<S, E> intoMap(Table<S> table, Class<? extends E> type) throws IllegalArgumentException,
InvalidResultException, MappingException;
/**
* Return a {@link Map} with results grouped by the given key table and
* mapped by the given mapper.
* <p>
* An {@link InvalidResultException} is thrown, if the keys are non-unique
* in the result set. Use {@link #intoGroups(Table, Class)} instead, if your
* keys are non-unique.
*
* @param table The key table. Client code must assure that keys are unique
* in the result set. May not be <code>null</code>.
* @param mapper The mapper callback.
* @return A Map containing the results.
* @throws IllegalArgumentException If any of the argument fields is not
* contained in {@link #fieldsRow()}
* @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 DefaultRecordMapper
*/
<E, S extends Record> Map<S, E> intoMap(Table<S> table, RecordMapper<? super R, E> mapper) throws IllegalArgumentException,
InvalidResultException, MappingException;
/**
* Return a {@link Map} with one of the result's columns as key and a list
* of corresponding records as value.
@ -817,20 +881,6 @@ public interface Result<R extends Record> extends List<R>, Attachable {
*/
<K, V> Map<K, List<V>> intoGroups(Field<K> key, Field<V> value) throws IllegalArgumentException;
/**
* 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.
*
* @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 IllegalArgumentException If any of the argument fields is not
* contained in {@link #fieldsRow()}
*/
Map<Record, Result<R>> intoGroups(Field<?>[] keys) throws IllegalArgumentException;
/**
* Return a {@link Map} with results grouped by the given key and mapped
* into the given entity type.
@ -865,6 +915,20 @@ public interface Result<R extends Record> extends List<R>, Attachable {
<K, E> Map<K, List<E>> intoGroups(Field<K> key, RecordMapper<? super R, E> mapper) throws IllegalArgumentException,
MappingException;
/**
* 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.
*
* @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 IllegalArgumentException If any of the argument fields is not
* contained in {@link #fieldsRow()}
*/
Map<Record, Result<R>> intoGroups(Field<?>[] keys) throws IllegalArgumentException;
/**
* Return a {@link Map} with results grouped by the given keys and mapped
* into the given entity type.
@ -889,7 +953,7 @@ public interface Result<R extends Record> extends List<R>, Attachable {
* 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
* Unlike {@link #intoMap(Field[], RecordMapper)}, 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
@ -905,6 +969,57 @@ public interface Result<R extends Record> extends List<R>, Attachable {
<E> Map<Record, List<E>> intoGroups(Field<?>[] keys, RecordMapper<? super R, E> mapper)
throws IllegalArgumentException, MappingException;
/**
* Return a {@link Map} with the result grouped by the given key table.
* <p>
* Unlike {@link #intoMap(Table)}, this method allows for non-unique keys in
* the result set.
*
* @param table The key table. May not be <code>null</code>.
* @return A Map containing grouped results
* @throws IllegalArgumentException If any of the argument fields is not
* contained in {@link #fieldsRow()}
*/
<S extends Record> Map<S, Result<R>> intoGroups(Table<S> table) throws IllegalArgumentException;
/**
* Return a {@link Map} with results grouped by the given key table and
* mapped into the given entity type.
* <p>
* Unlike {@link #intoMap(Table, Class)}, this method allows for non-unique
* keys in the result set.
*
* @param table The key table. May not be <code>null</code>.
* @param type The entity type.
* @return A Map containing grouped results
* @throws IllegalArgumentException If the any of the argument fields is not
* contained in {@link #fieldsRow()}
* @throws MappingException wrapping any reflection or data type conversion
* exception that might have occurred while mapping records
* @see DefaultRecordMapper
*/
<E, S extends Record> Map<S, List<E>> intoGroups(Table<S> table, Class<? extends E> type)
throws IllegalArgumentException, MappingException;
/**
* Return a {@link Map} with results grouped by the given key table and
* mapped into the given entity type.
* <p>
* Unlike {@link #intoMap(Table, RecordMapper)}, this method allows for
* non-unique keys in the result set.
*
* @param table The key table. May not be <code>null</code>.
* @param mapper The mapper callback.
* @return A Map containing grouped results
* @throws IllegalArgumentException If the any of the argument fields is not
* contained in {@link #fieldsRow()}
* @throws MappingException wrapping any reflection or data type conversion
* exception that might have occurred while mapping records
* @see DefaultRecordMapper
*/
<E, S extends Record> Map<S, List<E>> intoGroups(Table<S> table, RecordMapper<? super R, E> mapper)
throws IllegalArgumentException, MappingException;
/**
* Convert this result into an array of arrays.
* <p>

View File

@ -825,15 +825,15 @@ public interface ResultQuery<R extends Record> extends Query {
* @see Result#intoMap(Field[], Class)
* @see DefaultRecordMapper
*/
<E> Map<List<?>, E> fetchMap(Field<?>[] keys, Class<? extends E> type) throws MappingException;
<E> Map<List<?>, E> fetchMap(Field<?>[] keys, Class<? extends E> type) throws DataAccessException, MappingException;
/**
* Execute the query and return a {@link Map} with results grouped by the
* given keys and mapped by the given mapper.
* <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.
* in the result set. Use {@link #fetchGroups(Field[], RecordMapper)}
* 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,
@ -848,7 +848,72 @@ public interface ResultQuery<R extends Record> extends Query {
* @see Result#intoMap(Field[], Class)
* @see DefaultRecordMapper
*/
<E> Map<List<?>, E> fetchMap(Field<?>[] keys, RecordMapper<? super R, E> mapper) throws MappingException;
<E> Map<List<?>, E> fetchMap(Field<?>[] keys, RecordMapper<? super R, E> mapper) throws DataAccessException,
MappingException;
/**
* Execute the query and return a {@link Map} with table as a map key and the
* corresponding record as value.
* <p>
* An exception is thrown, if the keys turn out to be non-unique in the
* result set. Use {@link #fetchGroups(Table)} instead, if your keys are
* non-unique.
*
* @param table The key table. Client code must assure that keys are unique
* in the result set. May not be <code>null</code>.
* @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(Table)
*/
<S extends Record> Map<S, R> fetchMap(Table<S> table) throws DataAccessException;
/**
* Execute the query and return a {@link Map} with results grouped by the
* given table 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(Table, Class)} instead, if
* your keys are non-unique.
*
* @param table The key table. Client code must assure that keys are unique
* in the result set. May not be <code>null</code>.
* @param type The entity type.
* @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(Table, Class)
* @see DefaultRecordMapper
*/
<E, S extends Record> Map<S, E> fetchMap(Table<S> table, Class<? extends E> type) throws DataAccessException,
MappingException;
/**
* Execute the query and return a {@link Map} with results grouped by the
* given table and mapped by the given mapper.
* <p>
* An {@link InvalidResultException} is thrown, if the keys are non-unique
* in the result set. Use {@link #fetchGroups(Table, RecordMapper)} instead,
* if your keys are non-unique.
*
* @param table The key table. Client code must assure that keys are unique
* in the result set. May not be <code>null</code>.
* @param mapper The mapper callback.
* @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(Table, Class)
* @see DefaultRecordMapper
*/
<E, S extends Record> Map<S, E> fetchMap(Table<S> table, RecordMapper<? super R, E> mapper)
throws DataAccessException, MappingException;
/**
* Execute the query and return a {@link Map} with results grouped by the
@ -931,7 +996,9 @@ public interface ResultQuery<R extends Record> extends Query {
* Unlike {@link #fetchMap(Field[])}, this method allows for non-unique keys
* in the result set.
*
* @param keys The keys used for result grouping.
* @param keys The keys used for result grouping. 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
* @see Result#intoGroups(Field[])
@ -961,7 +1028,7 @@ public interface ResultQuery<R extends Record> extends Query {
* Execute the query and return a {@link Map} with results grouped by the
* given keys and mapped by the given mapper.
* <p>
* Unlike {@link #fetchMap(Field[], Class)}, this method allows for
* Unlike {@link #fetchMap(Field[], RecordMapper)}, 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
@ -976,6 +1043,58 @@ public interface ResultQuery<R extends Record> extends Query {
*/
<E> Map<Record, List<E>> fetchGroups(Field<?>[] keys, RecordMapper<? super R, E> mapper) throws MappingException;
/**
* Execute the query and return a {@link Map} with the result grouped by the
* given table.
* <p>
* Unlike {@link #fetchMap(Table)}, this method allows for non-unique keys
* in the result set.
*
* @param table The key table. May not be <code>null</code>.
* @return A Map containing grouped results
* @throws DataAccessException if something went wrong executing the query
* @see Result#intoGroups(Field[])
*/
<S extends Record> Map<S, Result<R>> fetchGroups(Table<S> table) throws DataAccessException;
/**
* Execute the query and return a {@link Map} with results grouped by the
* given table and mapped into the given entity type.
* <p>
* Unlike {@link #fetchMap(Table, Class)}, this method allows for non-unique
* keys in the result set.
*
* @param table The key table. May not be <code>null</code>.
* @param type The entity type.
* @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(Table, Class)
* @see DefaultRecordMapper
*/
<E, S extends Record> Map<S, List<E>> fetchGroups(Table<S> table, Class<? extends E> type)
throws DataAccessException, MappingException;
/**
* Execute the query and return a {@link Map} with results grouped by the
* given table and mapped by the given mapper.
* <p>
* Unlike {@link #fetchMap(Table, RecordMapper)}, this method allows for
* non-unique keys in the result set.
*
* @param table The key table. May not be <code>null</code>.
* @param mapper The mapper callback.
* @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(Table, Class)
* @see DefaultRecordMapper
*/
<E, S extends Record> Map<S, List<E>> fetchGroups(Table<S> table, RecordMapper<? super R, E> mapper)
throws DataAccessException, MappingException;
/**
* Return a {@link Map} with results grouped by the given key and mapped
* into the given entity type.

View File

@ -610,6 +610,21 @@ abstract class AbstractResultQuery<R extends Record> extends AbstractQuery imple
return fetch().intoMap(keys, mapper);
}
@Override
public final <S extends Record> Map<S, R> fetchMap(Table<S> table) {
return fetch().intoMap(table);
}
@Override
public final <E, S extends Record> Map<S, E> fetchMap(Table<S> table, Class<? extends E> type) {
return fetch().intoMap(table, type);
}
@Override
public final <E, S extends Record> Map<S, E> fetchMap(Table<S> table, RecordMapper<? super R, E> mapper) {
return fetch().intoMap(table, mapper);
}
@Override
public final <K, E> Map<K, E> fetchMap(Field<K> key, Class<? extends E> type) {
return fetch().intoMap(key, type);
@ -650,6 +665,21 @@ abstract class AbstractResultQuery<R extends Record> extends AbstractQuery imple
return fetch().intoGroups(keys, mapper);
}
@Override
public final <S extends Record> Map<S, Result<R>> fetchGroups(Table<S> table) {
return fetch().intoGroups(table);
}
@Override
public final <E, S extends Record> Map<S, List<E>> fetchGroups(Table<S> table, Class<? extends E> type) {
return fetch().intoGroups(table, type);
}
@Override
public final <E, S extends Record> Map<S, List<E>> fetchGroups(Table<S> table, RecordMapper<? super R, E> mapper) {
return fetch().intoGroups(table, mapper);
}
@Override
public final <K, E> Map<K, List<E>> fetchGroups(Field<K> key, Class<? extends E> type) {
return fetch().intoGroups(key, type);

View File

@ -1041,6 +1041,41 @@ class ResultImpl<R extends Record> implements Result<R>, AttachableInternal {
return map;
}
@Override
public final <S extends Record> Map<S, R> intoMap(Table<S> table) {
Map<S, R> map = new LinkedHashMap<S, R>();
for (R record : this) {
S key = record.into(table);
if (map.put(key, record) != null) {
throw new InvalidResultException("Key list " + key + " is not unique in Result for " + this);
}
}
return map;
}
@Override
public final <E, S extends Record> Map<S, E> intoMap(Table<S> table, Class<? extends E> type) {
return intoMap(table, Utils.configuration(this).recordMapperProvider().provide(fields, type));
}
@Override
public final <E, S extends Record> Map<S, E> intoMap(Table<S> table, RecordMapper<? super R, E> mapper) {
Map<S, E> map = new LinkedHashMap<S, E>();
for (R record : this) {
S key = record.into(table);
if (map.put(key, mapper.map(record)) != null) {
throw new InvalidResultException("Key list " + key + " 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) {
return intoMap(key, Utils.configuration(this).recordMapperProvider().provide(fields, type));
@ -1103,6 +1138,31 @@ class ResultImpl<R extends Record> implements Result<R>, AttachableInternal {
return map;
}
@Override
public final <K, E> Map<K, List<E>> intoGroups(Field<K> key, Class<? extends E> type) {
return intoGroups(key, Utils.configuration(this).recordMapperProvider().provide(fields, type));
}
@Override
public final <K, E> Map<K, List<E>> intoGroups(Field<K> key, RecordMapper<? super R, E> mapper) {
int index = indexOrFail(fieldsRow(), key);
Map<K, List<E>> map = new LinkedHashMap<K, List<E>>();
for (R record : this) {
K keyVal = (K) record.getValue(index);
List<E> list = map.get(keyVal);
if (list == null) {
list = new ArrayList<E>();
map.put(keyVal, list);
}
list.add(mapper.map(record));
}
return map;
}
@Override
public final Map<Record, Result<R>> intoGroups(Field<?>[] keys) {
if (keys == null) {
@ -1129,31 +1189,6 @@ class ResultImpl<R extends Record> implements Result<R>, AttachableInternal {
return map;
}
@Override
public final <K, E> Map<K, List<E>> intoGroups(Field<K> key, Class<? extends E> type) {
return intoGroups(key, Utils.configuration(this).recordMapperProvider().provide(fields, type));
}
@Override
public final <K, E> Map<K, List<E>> intoGroups(Field<K> key, RecordMapper<? super R, E> mapper) {
int index = indexOrFail(fieldsRow(), key);
Map<K, List<E>> map = new LinkedHashMap<K, List<E>>();
for (R record : this) {
K keyVal = (K) record.getValue(index);
List<E> list = map.get(keyVal);
if (list == null) {
list = new ArrayList<E>();
map.put(keyVal, list);
}
list.add(mapper.map(record));
}
return map;
}
@Override
public final <E> Map<Record, List<E>> intoGroups(Field<?>[] keys, Class<? extends E> type) {
return intoGroups(keys, Utils.configuration(this).recordMapperProvider().provide(fields, type));
@ -1185,6 +1220,49 @@ class ResultImpl<R extends Record> implements Result<R>, AttachableInternal {
return map;
}
@Override
public final <S extends Record> Map<S, Result<R>> intoGroups(Table<S> table) {
Map<S, Result<R>> map = new LinkedHashMap<S, Result<R>>();
for (R record : this) {
S key = record.into(table);
Result<R> result = map.get(key);
if (result == null) {
result = new ResultImpl<R>(configuration(), this.fields);
map.put(key, result);
}
result.add(record);
}
return map;
}
@Override
public final <E, S extends Record> Map<S, List<E>> intoGroups(Table<S> table, Class<? extends E> type) {
return intoGroups(table, Utils.configuration(this).recordMapperProvider().provide(fields, type));
}
@Override
public final <E, S extends Record> Map<S, List<E>> intoGroups(Table<S> table, RecordMapper<? super R, E> mapper) {
Map<S, List<E>> map = new LinkedHashMap<S, List<E>>();
for (R record : this) {
S key = record.into(table);
List<E> list = map.get(key);
if (list == null) {
list = new ArrayList<E>();
map.put(key, list);
}
list.add(mapper.map(record));
}
return map;
}
@Override
public final Object[][] intoArray() {
int size = size();

View File

@ -2540,6 +2540,21 @@ class SelectImpl<R extends Record, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
return getDelegate().fetchMap(keys, mapper);
}
@Override
public final <S extends Record> Map<S, R> fetchMap(Table<S> table) {
return getDelegate().fetchMap(table);
}
@Override
public final <E, S extends Record> Map<S, E> fetchMap(Table<S> table, Class<? extends E> type) {
return getDelegate().fetchMap(table, type);
}
@Override
public final <E, S extends Record> Map<S, E> fetchMap(Table<S> table, RecordMapper<? super R, E> mapper) {
return getDelegate().fetchMap(table, mapper);
}
@Override
public final <K, E> Map<K, E> fetchMap(Field<K> key, Class<? extends E> type) {
return getDelegate().fetchMap(key, type);
@ -2580,6 +2595,21 @@ class SelectImpl<R extends Record, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
return getDelegate().fetchGroups(keys, mapper);
}
@Override
public final <S extends Record> Map<S, Result<R>> fetchGroups(Table<S> table) {
return getDelegate().fetchGroups(table);
}
@Override
public final <E, S extends Record> Map<S, List<E>> fetchGroups(Table<S> table, Class<? extends E> type) {
return getDelegate().fetchGroups(table, type);
}
@Override
public final <E, S extends Record> Map<S, List<E>> fetchGroups(Table<S> table, RecordMapper<? super R, E> mapper) {
return getDelegate().fetchGroups(table, mapper);
}
@Override
public final <K, E> Map<K, List<E>> fetchGroups(Field<K> key, Class<? extends E> type) {
return getDelegate().fetchGroups(key, type);