InnerSelectContext.java

package org.microspace.table.query.sql;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.microspace.annotation.IndexType;
import org.microspace.space.SimpleSpace;
import org.microspace.table.Entry;
import org.microspace.table.SimpleTable;
import org.microspace.table.column.Accessor;
import org.microspace.table.column.GetSetPair;
import org.microspace.table.column.IndexedMap;
import org.microspace.table.column.IndexedSet;
import org.microspace.table.query.SimpleSqlQuery;

/**
 * @author Gaspar Sinai - {@literal gaspar.sinai@microspace.org}
 * @version 2017-07-06
 */
public class InnerSelectContext<T> {

	private SimpleSpace space;
	
	private Class<T>    queryTableClass;
	private IndexedMap<Object, Entry<T>> entries;
	
	private Map<String, IndexedSet<Object>> selectCache = new HashMap<>();
	
	public InnerSelectContext(SimpleSpace space, Class<T> queryTableClass) {
		this.space = space;
		this.queryTableClass = queryTableClass;
	}
	
	public IndexedMap<Object, Entry<T>> getEntries() {
		return entries;
	}
	public void setEntries(IndexedMap<Object, Entry<T>> entries) {
		this.entries = entries;
	}

	public Class<?> getQueryTableClass() {
		return queryTableClass;
	}

	public SimpleSpace getSpace() {
		return space;
	}
	
	public void putInnerSelect (Select<?> select) {
		IndexedSet<Object> value = performInnerSelect(select);
		selectCache.put(select.getId(), value);
	}
	
	public IndexedSet<Object> get (String id) {
		return selectCache.get (id);
	}

	private IndexedSet<Object> performInnerSelect(Select<?> innerSelect) {
		if (innerSelect.isTopLevel()) {
			throw new IllegalArgumentException("Inner Select Expected");
		}
		if (innerSelect.getColumnNames().size() != 1) {
			throw new IllegalArgumentException("Inner Select Column Name Expected");
		}
		SimpleSqlQuery<?> sql = new SimpleSqlQuery<>(innerSelect);
		List<?> list = space.readMultiple(sql);
		return addAll(sql.getId(), innerSelect.getColumnNames().get(0), list);
	}

	private <IT> IndexedSet<Object> addAll(String id, String columnName, List<IT> list) {

		if (list.size() == 0) {
			return new IndexedSet<Object>(IndexType.HASHED);
		}
		SimpleTable<IT> table = space.getMap(list.get(0).getClass(), false);
		if (table == null) {
			return new IndexedSet<Object>(IndexType.HASHED);
		}
		Accessor<IT> accessor = table.getAccessor();
		GetSetPair<IT> pair = accessor.getGetSetPair(columnName);
		IndexType type;
		if (pair.getIndexType() == null) {
			type = Comparable.class.isAssignableFrom(pair.getReturnType()) ? IndexType.SORTED : IndexType.HASHED;
		} else {
			type = pair.getIndexType();
		}
		IndexedSet<Object> retSet = new IndexedSet<Object>(type);
		for (IT target : list) {
			Object field = pair.get(target);
			if (field == null) {
				continue;
			}
			retSet.add(field);
		}
		return retSet;
	}

}