More working tests.
[castle.git] / MonoRail / Castle.MonoRail.ActiveRecordSupport / Pagination / AbstractPaginableQuery.cs
blob7e975c162fd06f3255965585ef191f16293b55ec
1 // Copyright 2004-2008 Castle Project - http://www.castleproject.org/
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
15 namespace Castle.MonoRail.ActiveRecordSupport.Pagination
17 using System;
18 using System.Collections;
20 using Castle.ActiveRecord;
21 using Castle.ActiveRecord.Framework;
23 using NHibernate;
25 /// <summary>
26 /// Base class for all paginable queries, including custom ones.
27 /// </summary>
28 /// <remarks>
29 /// Extenders should override the <see cref="BuildHQL"/>.
30 /// Optionally, the methods <see cref="SetQueryParameters"/>
31 /// and <see cref="ExecuteQuery"/> can also be overriden.
32 /// </remarks>
33 public abstract class AbstractPaginableQuery : ActiveRecordBaseQuery, IARPaginableDataSource
35 protected int pageSize, currentPage;
37 public AbstractPaginableQuery(Type targetType) : base(targetType)
41 /// <summary>
42 /// Executes a query to return the record count
43 /// </summary>
44 public virtual int ObtainCount()
46 ISessionFactoryHolder holder = ActiveRecordMediator.GetSessionFactoryHolder();
47 ISession session = holder.CreateSession(RootType);
49 try
51 IQuery query = session.CreateQuery(BuildCountHQL());
52 SetQueryParameters(query);
54 return (int) query.UniqueResult();
56 catch (HibernateException)
58 return -1;
60 finally
62 holder.ReleaseSession(session);
66 protected virtual string BuildCountHQL()
68 return "select count(*) from (" + BuildHQL() + ")";
71 /// <summary>
72 /// Returns the page items.
73 /// Actually, the implementation just sets the protected fields
74 /// <see cref="pageSize"/> and <see cref="currentPage"/>,
75 /// gets an <see cref="ISession" /> from <c>SessionFactoryHolder</c>
76 /// and calls <see cref="InternalExecute"/> in order to execute
77 /// the custom query and fetch only the page items.
78 /// </summary>
79 /// <param name="pageSize">The page size</param>
80 /// <param name="currentPage">The current page</param>
81 /// <returns>The page items</returns>
82 public virtual IEnumerable Paginate(int pageSize, int currentPage)
84 this.pageSize = pageSize;
85 this.currentPage = currentPage;
87 ISessionFactoryHolder holder = ActiveRecordMediator.GetSessionFactoryHolder();
88 ISession session = holder.CreateSession(RootType);
90 try
92 return InternalPaginate(session, false);
94 finally
96 holder.ReleaseSession(session);
100 public virtual IEnumerable ListAll()
102 return (IEnumerable) ActiveRecordMediator.ExecuteQuery(this);
105 /// <summary>
106 /// The implementation of the <see cref="InternalExecute"/> method,
107 /// as required by <see cref="ActiveRecordBaseQuery"/>.
108 /// Should not be overriden.
109 /// </summary>
110 /// <param name="session">The NHibernate Session</param>
111 /// <returns>The query results.</returns>
112 protected sealed override object InternalExecute(ISession session)
114 return InternalPaginate(session, true);
117 /// <summary>
118 /// The implementation of the <see cref="InternalEnumerate"/> method,
119 /// as required by <see cref="ActiveRecordBaseQuery"/>.
120 /// Should not be overriden.
121 /// </summary>
122 /// <param name="session">The NHibernate Session</param>
123 /// <returns>The query results.</returns>
124 protected sealed override IEnumerable InternalEnumerate(ISession session)
126 return InternalPaginate(session, true);
129 private IEnumerable InternalPaginate(ISession session, bool skipPagination)
131 IQuery query = CreateQuery(session);
133 if (!skipPagination)
135 PrepareQueryForPagination(query);
138 return ExecuteQuery(query);
141 protected sealed override IQuery CreateQuery(ISession session)
143 IQuery query = session.CreateQuery(BuildHQL());
144 SetQueryParameters(query);
145 return query;
148 /// <summary>
149 /// For internal use only.
150 /// </summary>
151 private void PrepareQueryForPagination(IQuery query)
153 query.SetFirstResult(pageSize * (currentPage-1));
154 query.SetMaxResults(pageSize);
157 /// <summary>
158 /// Should be overriden to return the custom HQL to be ran.
159 /// </summary>
160 /// <returns>The custom HQL to be ran</returns>
161 protected abstract string BuildHQL();
163 /// <summary>
164 /// May be overriden, in order to set custom query parameters.
165 /// </summary>
166 /// <param name="query">The query</param>
167 protected virtual void SetQueryParameters(IQuery query) { }
169 /// <summary>
170 /// Override to provide a custom query execution.
171 /// The default behaviour is to just call <see cref="IQuery.List()"/>.
172 /// </summary>
173 /// <param name="query">The query</param>
174 /// <returns>The query results.</returns>
175 protected virtual IEnumerable ExecuteQuery(IQuery query)
177 return query.List();