package io.cattle.platform.db.jooq.mapper; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.jooq.Field; import org.jooq.Record; import org.jooq.RecordMapper; import org.jooq.Table; public abstract class MultiRecordMapper<T> implements RecordMapper<Record, T> { protected List<Table<?>> tables = new ArrayList<Table<?>>(); protected List<Class<? extends Record>> classes = new ArrayList<Class<? extends Record>>(); protected Map<String, Target> targets = new HashMap<String, MultiRecordMapper.Target>(); protected List<Field<?>> fields = new ArrayList<Field<?>>(); protected int count = 0; @SuppressWarnings({ "unchecked", "hiding" }) public <T extends Table<?>> T add(T input, Field<?>... selectedFields) { Set<String> selectFields = selectedFields == null || selectedFields.length == 0 ? null : new HashSet<String>(); int index = count++; String prefix = String.format("%s_%d", input.getName(), index); Table<?> alias = input.as(prefix); for (Field<?> field : selectedFields) { selectFields.add(field.getName()); } for (Field<?> field : alias.fields()) { if (selectFields != null && !"id".equals(field.getName()) && !selectFields.contains(field.getName())) { continue; } String fieldAlias = String.format("%s_%s", prefix, field.getName()); Target target = new Target(field.getName(), index); targets.put(fieldAlias, target); fields.add(field.as(String.format("%s_%s", prefix, field.getName()))); } classes.add(input.getRecordType()); return (T) alias; } @Override public T map(Record record) { List<Map<String, Object>> maps = new ArrayList<Map<String, Object>>(classes.size()); for (int i = 0; i < classes.size(); i++) { maps.add(new HashMap<String, Object>()); } Map<String, Object> row = record.intoMap(); for (Map.Entry<String, Object> entry : row.entrySet()) { Target target = targets.get(entry.getKey()); if (target == null) { continue; } Map<String, Object> map = maps.get(target.index); Object value = entry.getValue(); if (value != null) { map.put(target.fieldName, value); } } List<Object> result = new ArrayList<Object>(); for (int i = 0; i < maps.size(); i++) { try { Map<String, Object> map = maps.get(i); if (map.size() > 0) { Record resultRecord = classes.get(i).newInstance(); resultRecord.fromMap(map); resultRecord.changed(false); result.add(resultRecord); } else { result.add(null); } } catch (InstantiationException e) { throw new IllegalStateException(e); } catch (IllegalAccessException e) { throw new IllegalStateException(e); } } return map(result); } protected abstract T map(List<Object> input); public List<Field<?>> fields() { return fields; } private final static class Target { String fieldName; int index; public Target(String fieldName, int index) { super(); this.fieldName = fieldName; this.index = index; } } }