package com.peterphi.std.guice.hibernate.webquery;

import com.peterphi.std.guice.restclient.jaxb.webquery.WebQuery;

import java.util.Collections;
import java.util.List;

public class ConstrainedResultSet<T>
{
	protected /*final*/ ResultSetConstraint constraint;
	protected /*final*/ WebQuery query;
	protected List<String> sql = Collections.emptyList();
	protected final List<T> list;

	protected Long total;


	public ConstrainedResultSet(ResultSetConstraint constraint, List<T> list)
	{
		if (constraint == null)
			throw new IllegalArgumentException("Must provide non-null ResultSetConstraint!");

		this.constraint = constraint;
		this.query = null;
		this.list = list;
	}


	public ConstrainedResultSet(WebQuery query, List<T> list)
	{
		if (query == null)
			throw new IllegalArgumentException("Must provide non-null ResultSetConstraint!");
		this.constraint = null;
		this.query = query;
		this.list = list;
	}


	public int getOffset()
	{
		if (constraint != null)
			return constraint.getOffset();
		else
			return query.constraints.offset;
	}


	public int getLimit()
	{
		if (constraint != null)
			return constraint.getLimit();
		else
			return query.constraints.limit;
	}


	public List<T> getList()
	{
		return list;
	}


	/**
	 * @return
	 *
	 * @deprecated use WebQueryDefinition instead
	 */
	@Deprecated
	public ResultSetConstraint getConstraint()
	{
		if (constraint == null)
			return new ResultSetConstraint(getQuery().encode());

		return constraint;
	}


	public WebQuery getQuery()
	{
		if (query == null)
			query = constraint.toQuery();

		return query;
	}


	public Long getTotal()
	{
		return total;
	}


	public void setTotal(final Long total)
	{
		this.total = total;
	}


	public List<String> getSql()
	{
		return sql;
	}


	public void setSql(final List<String> sql)
	{
		this.sql = sql;
	}
}

@@ -1818,10 +1818,864 @@
 sql;%0A%09%7D%0A
+%0A%0A%09/**%0A%09 * When exactly one result is expected, returns that result or throws %7B@link IllegalArgumentException%7D if too many or too few%0A%09 * results were returned%0A%09 *%0A%09 * @return%0A%09 */%0A%09public T one()%0A%09%7B%0A%09%09final T obj = uniqueResult();%0A%0A%09%09if (obj != null)%0A%09%09%09return obj;%0A%09%09else%0A%09%09%09throw new IllegalArgumentException(%22Asked for single result but resultset contained 0 results!%22);%0A%09%7D%0A%0A%0A%09/**%0A%09 * When a single result is expected, returns that result (or null if no results were returned). Throws an %7B@link%0A%09 * IllegalArgumentException%7D if more than one results were returned%0A%09 *%0A%09 * @return%0A%09 */%0A%09public T uniqueResult()%0A%09%7B%0A%09%09if (list == null %7C%7C list.size() == 0)%0A%09%09%09return null;%0A%09%09else if (list.size() == 1)%0A%09%09%09return list.get(0);%0A%09%09else%0A%09%09%09throw new IllegalArgumentException(%22Asked for unique result but resultset contained %22 + list.size() + %22 results!%22);%0A%09%7D%0A
 %7D%0A

Add helper methods uniqueResult() and one() for ConstrainedResultSet