1 // Copyright 2004-2008 Castle Project - http://www.castleproject.org/
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
7 // http://www.apache.org/licenses/LICENSE-2.0
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
18 using System
.Collections
;
20 using Castle
.ActiveRecord
;
21 using Castle
.ActiveRecord
.Framework
;
26 /// Base class for all paginable queries, including custom ones.
29 /// Extenders should override the <see cref="BuildHQL"/>.
30 /// Optionally, the methods <see cref="SetQueryParameters"/>
31 /// and <see cref="ExecuteQuery"/> can also be overriden.
33 public abstract class AbstractPaginableQuery
: ActiveRecordBaseQuery
, IARPaginableDataSource
35 protected int pageSize
, currentPage
;
37 public AbstractPaginableQuery(Type targetType
) : base(targetType
)
42 /// Executes a query to return the record count
44 public virtual int ObtainCount()
46 ISessionFactoryHolder holder
= ActiveRecordMediator
.GetSessionFactoryHolder();
47 ISession session
= holder
.CreateSession(RootType
);
51 IQuery query
= session
.CreateQuery(BuildCountHQL());
52 SetQueryParameters(query
);
54 return (int) query
.UniqueResult();
56 catch (HibernateException
)
62 holder
.ReleaseSession(session
);
66 protected virtual string BuildCountHQL()
68 return "select count(*) from (" + BuildHQL() + ")";
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.
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
);
92 return InternalPaginate(session
, false);
96 holder
.ReleaseSession(session
);
100 public virtual IEnumerable
ListAll()
102 return (IEnumerable
) ActiveRecordMediator
.ExecuteQuery(this);
106 /// The implementation of the <see cref="InternalExecute"/> method,
107 /// as required by <see cref="ActiveRecordBaseQuery"/>.
108 /// Should not be overriden.
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);
118 /// The implementation of the <see cref="InternalEnumerate"/> method,
119 /// as required by <see cref="ActiveRecordBaseQuery"/>.
120 /// Should not be overriden.
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
);
135 PrepareQueryForPagination(query
);
138 return ExecuteQuery(query
);
141 protected sealed override IQuery
CreateQuery(ISession session
)
143 IQuery query
= session
.CreateQuery(BuildHQL());
144 SetQueryParameters(query
);
149 /// For internal use only.
151 private void PrepareQueryForPagination(IQuery query
)
153 query
.SetFirstResult(pageSize
* (currentPage
-1));
154 query
.SetMaxResults(pageSize
);
158 /// Should be overriden to return the custom HQL to be ran.
160 /// <returns>The custom HQL to be ran</returns>
161 protected abstract string BuildHQL();
164 /// May be overriden, in order to set custom query parameters.
166 /// <param name="query">The query</param>
167 protected virtual void SetQueryParameters(IQuery query
) { }
170 /// Override to provide a custom query execution.
171 /// The default behaviour is to just call <see cref="IQuery.List()"/>.
173 /// <param name="query">The query</param>
174 /// <returns>The query results.</returns>
175 protected virtual IEnumerable
ExecuteQuery(IQuery query
)