// Persist library : Persistence layer
// Copyright (C) 2003 Vincent Daron
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
using System;
using System.Collections;
using Persist.Sql;
using Persist.Maps;
using Persist.Criteria;
namespace Persist.Statements{
/// <summary>
/// the Statement used to execute SELECT Query
/// </summary>
public class RetrieveStatement : Statements.PersistentStatement
{
private bool isDistinct = false;
private ArrayList groupAttributes = new ArrayList();
private ArrayList orderAttributes = new ArrayList();
private CriteriaConditionSet havingCondition = null;
/// <summary>
/// Create a RetrieveCriteria
/// </summary>
/// <param name="criteriaType">the Type of the object to retrieve</param>
public RetrieveStatement(Type criteriaType):base(criteriaType)
{
havingCondition = base.GetNewConditionSet();
}
/// <summary>
/// Create a RetrieveCriteria based on a ClassMap
/// </summary>
/// <param name="classMap"></param>
internal RetrieveStatement(ClassMap classMap):base(classMap)
{
havingCondition = base.GetNewConditionSet();
}
/// <summary>
/// Creates a Retrieve Statement based on another Statement.
/// This is used in DeleteStatement Processing.
/// </summary>
/// <param name="statement">the Statement to copy</param>
internal RetrieveStatement(Statements.PersistentStatement statement):base(statement)
{
if(statement is RetrieveStatement)
havingCondition = ((RetrieveStatement)statement).havingCondition;
}
/// <summary>
/// Returns condition for the HAVING part of this criteria.
/// </summary>
public CriteriaConditionSet HavingCondition
{
get
{
return havingCondition;
}
}
/// <summary>
/// Specified if the result must return only one instance of each row
/// </summary>
public bool Distinct
{
get{return isDistinct;}
set{isDistinct = true;}
}
/// <summary>
/// Returns sql statement for this criteria.
/// </summary>
/// <param name="parameters">the Parameters</param>
/// <param name="forProxy">Indicate if the result must only include Proxy Objects</param>
/// <returns>the Statement</returns>
public SqlStatement GetSqlStatement(ICollection parameters, bool forProxy)
{
SqlStatement statement = null;
if(forProxy)
{
statement = base.ClassMap.GetSelectProxySql(isDistinct);
}
else
{
statement = base.ClassMap.GetSelectSql(isDistinct);
}
// Add 'FROM' clause to the select statement
statement.AddSqlClause(" " + base.ClassMap.RelationalDatabase.ClauseStringFrom + " ");
bool first = true;
foreach(TableMap tableMap in base.Tables)
{
statement.AddSqlClause((!first ? ", " : "") + tableMap.Name);
first = false;
}
// Fill statement with WHERE condition
base.FillStatementWithWhere(statement, parameters);
// Add GROUP BY clause
if(groupAttributes.Count > 0)
{
statement.AddSqlClause(" " + base.ClassMap.RelationalDatabase.ClauseStringGroupBy);
for(int i = 0; i < groupAttributes.Count; i++)
{
AttributeMap am = (AttributeMap)groupAttributes[i];
statement.AddSqlClause((i > 0 ? ", " : " ") + am.ColumnMap.FullyQualifiedName);
}
}
// Fill statement with HAVING condition
if(havingCondition != null && havingCondition.Count > 0)
{
statement.AddSqlClause(" " + base.ClassMap.RelationalDatabase.ClauseStringHaving + " ");
havingCondition.FillSqlStatement(statement, parameters);
}
// Add ORDER BY clause
if(orderAttributes.Count > 0)
{
statement.AddSqlClause(" " + base.ClassMap.RelationalDatabase.ClauseStringOrderBy);
for(int i = 0; i < orderAttributes.Count; i++)
{
OrderEntry entry = (OrderEntry)orderAttributes[i];
statement.AddSqlClause((i > 0 ? ", " : " ") + entry.AttributeMap.ColumnMap.FullyQualifiedName + " " +
(entry.isAscend ? base.ClassMap.RelationalDatabase.ClauseStringAscend : base.ClassMap.RelationalDatabase.ClauseStringDescend));
}
}
return statement;
}
/// <summary>
/// This method Execute this criteria.
/// </summary>
/// <param name="parameters">the Criteria parameters</param>
/// <returns>the Cursor with results</returns>
public Cursor Perform(ICollection parameters)
{
return Persist.PersistenceManagerFactory.Instance.ProcessStatement(this, parameters);
}
/// <summary>
/// Execute the Statement and return the firt result
/// </summary>
/// <param name="parameters">the Statement parameters</param>
/// <returns>the first query result, or null</returns>
public object PerformSingle(ICollection parameters)
{
object result = null;
using(Cursor c = Persist.PersistenceManagerFactory.Instance.ProcessStatement(this,parameters))
{
foreach(object val in c)
{
result = val;
break;
}
}
return result;
}
/// <summary>
/// This method performs this criteria to retrieve proxy objects.
/// </summary>
/// <param name="parameters">Query parameters</param>
/// <returns>Cursor with proxy objects</returns>
public Cursor PerformForProxies(ICollection parameters)
{
return Persist.PersistenceManagerFactory.Instance.ProcessStatementForProxies(this, parameters);
}
/// <summary>
/// Adds the specified attribute to the ORDER BY part of the statement
/// with the specified direction of sorting.
/// </summary>
/// <param name="attributeName">the Attribute name</param>
/// <param name="ascend">Sort Ascending</param>
public void AddOrderAttribute(string attributeName, bool ascend)
{
AttributeMap am = base.ClassMap.GetAttributeMap(attributeName, true);
if(am == null)
{
throw new Exception("Attribute "+attributeName+" not found in Class +"+base.ClassMap.TypeName);
}
orderAttributes.Add(new OrderEntry(am, ascend));
}
/// <summary>
/// Adds the specified attribute to the ORDER BY part of the statement
/// with the default direction of sorting.
/// </summary>
/// <param name="attributeName">the Attribute name</param>
public void AddOrderAttribute(string attributeName)
{
AddOrderAttribute(attributeName, true);
}
/// <summary>
/// Adds the specified attribute to the GROUP BY part of the statement.
/// </summary>
/// <param name="attributeName">the Attribute name</param>
public void AddGroupAttribute(string attributeName)
{
groupAttributes.Add(base.ClassMap.GetAttributeMap(attributeName, true));
}
}
}
|