gt: 		m_where = new StringBuilder("id=");
context: package db;
  
  public class Select
  {
  	private StringBuilder	m_columns = new StringBuilder();
  	private boolean			m_distinct;
  	private String			m_distinct_on;
  	private StringBuilder	m_from = new StringBuilder();
  	private String			m_group_by;
  	private int				m_limit;
  	private StringBuilder	m_order_by;
  	private StringBuilder	m_where;
  
      //--------------------------------------------------------------------------
  
  	public
  	Select(String columns)
  	{
  		m_columns.append(columns);
  	}
  
      //--------------------------------------------------------------------------
  
  	public void
  	addColumn(String column)
  	{
  		m_columns.append(',');
  		m_columns.append(column);
  	}
  
      //--------------------------------------------------------------------------
  
  	public void
  	addColumn(String column, String alias)
  	{
  		m_columns.append(',');
  		m_columns.append(column);
  		m_columns.append(" AS ");
  		m_columns.append(alias);
  	}
  
      //--------------------------------------------------------------------------
  
  	public void
  	addColumns(String columns)
  	{
  		if (columns.charAt(0) == '(' || m_columns.charAt(0) != '*') {
  			m_columns.append(',');
  			m_columns.append(columns);
  		}
  	}
  
      //--------------------------------------------------------------------------
  
  	public void
  	addFrom(String from)
  	{
  		if (m_from.length() > 0)
  			m_from.append(',');
  		m_from.append(from);
  	}
  
      //--------------------------------------------------------------------------
  	// doesn't add quotes, done by OrderBy.toQueryString() and passed in here
  
  	public void
  	addOrderBy(String order_by)
  	{
  		if (order_by == null || order_by.length() == 0)
  			return;
  		String[] columns = order_by.split(",");
  		for (String column : columns) {
  			if (m_order_by == null)
  				m_order_by = new StringBuilder();
  			else
  				m_order_by.append(',');
  			int index = column.indexOf(" AS ");
  			if (index != -1)
  				m_order_by.append(column.substring(index + 4));
  			else
  				m_order_by.append(column);
  		}
  	}
  
      //--------------------------------------------------------------------------
  
  	public void
  	addRelationColumn(String columns)
  	{
  		if (m_columns.charAt(0) == '*') {
  			m_columns.insert(0, '.');
  			m_columns.insert(0, (Object)m_from);
  		} else if (m_distinct && m_columns.charAt(9) == '*') {
  			m_columns.insert(9, '.');
  			m_columns.insert(9, (Object)m_from);
  		}
  		m_columns.append(',');
  		m_columns.append(columns);
  	}
  
      //--------------------------------------------------------------------------
  
  	public void
  	andWhere(String where)
  	{
  		if (m_where == null)
  			m_where = new StringBuilder();
  		else
  			m_where.append(" AND ");
  		m_where.append('(');
  		m_where.append(where);
  		m_where.append(')');
  	}
  
      //--------------------------------------------------------------------------
  
  	public Select
  	distinct()
  	{
  		m_distinct = true;
  		return this;
  	}
  
      //--------------------------------------------------------------------------
  
  	public Select
  	distinctOn(String distinct_on)
  	{
  		m_distinct = true;
  		m_distinct_on = distinct_on;
  		return this;
  	}
  
      //--------------------------------------------------------------------------
  
  	public Select
  	from(String from)
  	{
  		m_from.append(from);
  		return this;
  	}
  
      //--------------------------------------------------------------------------
  
  	public String
  	getColumns()
  	{
  		return m_columns.toString();
  	}
  
      //--------------------------------------------------------------------------
  
  	public String
  	getFirstTable()
  	{
  		int comma = m_from.indexOf(",");
  		int space = m_from.indexOf(" ");
  		if (comma != -1)
  			if (space != -1)
  				return m_from.substring(0, Math.min(comma, space));
  			else
  				return m_from.substring(0, comma);
  		if (space != -1)
  			return m_from.substring(0, space);
  		return m_from.toString();
  	}
  
      //--------------------------------------------------------------------------
  
  	public String
  	getFrom()
  	{
  		return m_from.toString();
  	}
  
      //--------------------------------------------------------------------------
  
  	public String
  	getOrderBy()
  	{
  		return m_order_by == null ? null : m_order_by.toString();
  	}
  
      //--------------------------------------------------------------------------
  
  	public String
  	getWhere()
  	{
  		return m_where == null ? null : m_where.toString();
  	}
  
      //--------------------------------------------------------------------------
  
  	public Select
  	groupBy(String group_by)
  	{
  		m_group_by = group_by;
  		return this;
  	}
  
      //--------------------------------------------------------------------------
  	// doesn't add quotes, done by OrderBy.toQueryString() and passed in here
  
  	public void
  	insertOrderBy(String order_by)
  	{
  		if (order_by == null || order_by.length() == 0)
  			return;
  		if (m_order_by == null)
  			m_order_by = new StringBuilder();
  		else
  			m_order_by.insert(0, ',');
  		m_order_by.insert(0, order_by);
  	}
  
      //--------------------------------------------------------------------------
  
  	public Select
  	join(String one_table, String many_table)
  	{
  		m_from.append(" JOIN ");
  		m_from.append(many_table);
  		m_from.append(" ON ");
  		m_from.append(one_table);
  		m_from.append(".id=");
  		m_from.append(many_table);
  		m_from.append('.');
  		m_from.append(one_table);
  		m_from.append("_id");
  		return this;
  	}
  
      //--------------------------------------------------------------------------
  
  	public Select
  	join(String one_table, String many_table, String many_to_many_table)
  	{
  		join(one_table, many_to_many_table);
  		m_from.append(" JOIN ");
  		m_from.append(many_table);
  		m_from.append(" ON ");
  		m_from.append(many_table);
  		m_from.append(".id=");
  		m_from.append(many_to_many_table);
  		m_from.append('.');
  		m_from.append(many_table);
  		m_from.append("_id");
  		return this;
  	}
  
      //--------------------------------------------------------------------------
  
  	public Select
  	joinOn(String many_table, String on)
  	{
  		m_from.append(" JOIN ");
  		m_from.append(many_table);
  		m_from.append(" ON ");
  		m_from.append(on);
  		return this;
  	}
  
      //--------------------------------------------------------------------------
  
  	public Select
  	leftJoin(String one_table, String many_table)
  	{
  		m_from.append(" LEFT");
  		return join(one_table, many_table);
  	}
  
      //--------------------------------------------------------------------------
  
  	public Select
  	leftJoin(String one_table, String many_table, String many_to_many_table)
  	{
  		m_from.append(" LEFT");
  		return join(one_table, many_table, many_to_many_table);
  	}
  
      //--------------------------------------------------------------------------
  
  	public Select
  	limit(int limit)
  	{
  		m_limit = limit;
  		return this;
  	}
  
      //--------------------------------------------------------------------------
  
  	public Select
  	orderBy(String order_by)
  	{
  		if (order_by != null) {
  			m_order_by = new StringBuilder();
  			m_order_by.append(order_by);
  		}
  		return this;
  	}
  
      //--------------------------------------------------------------------------
  
  	public Select
  	select(String columns)
  	{
  		m_columns.setLength(0);
  		m_columns.append(columns);
  		return this;
  	}
  
      //--------------------------------------------------------------------------
  
  	@Override
  	public String
  	toString()
  	{
  		StringBuilder sb = new StringBuilder("SELECT ");
  
  		if (m_distinct) {
  			sb.append("DISTINCT ");
  			if (m_distinct_on != null) {
  				sb.append("ON(");
  				if (m_order_by != null) {
  					sb.append(m_order_by.toString().replaceAll(" DESC", ""));
  					sb.append(',');
  				}
  				sb.append(m_distinct_on);
  				sb.append(')');
  			}
  		}
  		sb.append(m_columns);
  		sb.append(" FROM ");
  		sb.append(m_from);
  		if (m_where!= null && m_where.length() > 0) {
  			sb.append(" WHERE ");
  			sb.append(m_where);
  		}
  		if (m_group_by != null) {
  			sb.append(" GROUP BY ");
  			sb.append(m_group_by);
  		}
  		if (m_order_by != null) {
  			sb.append(" ORDER BY ");
  			sb.append(m_order_by);
  		}
  		if (m_limit > 0) {
  			sb.append(" LIMIT ");
  			sb.append(m_limit);
  		}
  
  		return sb.toString();
  	}
  
      //--------------------------------------------------------------------------
  
  	public Select
  	where(String where)
  	{
  		if (where != null && where.length() > 0) {
  			m_where = new StringBuilder();
  			m_where.append(where);
  		}
  		return this;
  	}
  
      //--------------------------------------------------------------------------
  
  	public Select
  	whereEquals(String column, int id)
  	{
  		m_where = new StringBuilder(column);
  		m_where.append('=');
  		m_where.append(id);
  		return this;
  	}
  
      //--------------------------------------------------------------------------
  
  	public Select
  	whereIdEquals(int id)
  	{
  