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
.ActiveRecord
18 using System
.Collections
;
20 using Castle
.ActiveRecord
.Framework
;
21 using Castle
.ActiveRecord
.Queries
;
22 using Castle
.ActiveRecord
.Queries
.Modifiers
;
23 using Castle
.Core
.Logging
;
28 /// Base class for all ActiveRecord queries.
30 public abstract class ActiveRecordBaseQuery
: IActiveRecordQuery
, ICloneable
32 private readonly Type rootType
;
34 private ILogger log
= NullLogger
.Instance
;
37 /// list of modifiers for the query
39 protected IList queryModifiers
;
42 /// Initializes a new instance of the <see cref="ActiveRecordBaseQuery"/> class.
44 /// <param name="rootType">The type.</param>
45 protected ActiveRecordBaseQuery(Type rootType
)
47 this.rootType
= rootType
;
51 /// Gets the target type of this query
55 get { return rootType; }
59 /// Use the specified logger to output diagnostic messages.
68 throw new ArgumentException("The logger could not be null, use NullLogger.Instance instead.");
74 #region IActiveRecordQuery implementation
77 /// Executes the specified query and return the results
79 /// <param name="session">The session to execute the query in.</param>
80 /// <returns></returns>
81 object IActiveRecordQuery
.Execute(ISession session
)
83 return InternalExecute(session
);
87 /// Enumerates over the result of the query.
88 /// Note: Only use if you expect most of your values to already exist in the second level cache!
90 /// <param name="session"></param>
91 /// <returns></returns>
92 IEnumerable IActiveRecordQuery
.Enumerate(ISession session
)
94 return InternalEnumerate(session
);
100 /// Simply creates the query and then call its <see cref="IQuery.List()"/> method.
102 /// <param name="session">The <c>NHibernate</c>'s <see cref="ISession"/></param>
103 protected virtual object InternalExecute(ISession session
)
105 return CreateQuery(session
).List();
109 /// Simply creates the query and then call its <see cref="IQuery.Enumerable()"/> method.
110 /// Note: Only use when you expect most of the results to be in the second level cache
112 /// <param name="session">The <c>NHibernate</c>'s <see cref="ISession"/></param>
113 protected virtual IEnumerable
InternalEnumerate(ISession session
)
115 return CreateQuery(session
).Enumerable();
119 /// Add this query to a multiquery
121 /// <param name="session">an <c>ISession</c> shared by all queries in the multiquery</param>
122 /// <param name="multiquery">the <c>IMultiQuery</c> that will receive the newly created query</param>
123 internal void AddQuery(ISession session
, IMultiQuery multiquery
)
125 IQuery query
= CreateQuery(session
);
126 multiquery
.Add(query
);
130 /// Creates the <see cref="IQuery" /> instance.
132 protected abstract IQuery
CreateQuery(ISession session
);
135 /// Just a default clone implementation...
137 public virtual object Clone()
139 ActiveRecordBaseQuery clone
= (ActiveRecordBaseQuery
) MemberwiseClone();
140 if (queryModifiers
!= null)
142 clone
.queryModifiers
= new ArrayList(queryModifiers
);
148 /// Adds a query modifier, to be applied with <see cref="ApplyModifiers"/>.
150 /// <param name="modifier">The modifier</param>
151 protected void AddModifier(IQueryModifier modifier
)
153 if (queryModifiers
== null)
155 queryModifiers
= new ArrayList();
158 queryModifiers
.Add(modifier
);
162 /// Applies the modifiers added with <see cref="AddModifier"/>.
164 /// <param name="query">The query in which to apply the modifiers</param>
166 /// This method is not called automatically
167 /// by <see cref="ActiveRecordBaseQuery"/>, but is called from
168 /// <see cref="HqlBasedQuery"/>.
170 protected void ApplyModifiers(IQuery query
)
172 if (queryModifiers
!= null)
174 foreach(IQueryModifier modifier
in queryModifiers
)
176 modifier
.Apply(query
);
182 /// Converts the results stored in an <see cref="IList"/> to an
183 /// strongly-typed array.
185 /// <param name="t">The type of the new array</param>
186 /// <param name="list">The source list</param>
187 /// <param name="distinct">If true, only distinct results will be inserted in the array</param>
188 /// <returns>The strongly-typed array</returns>
189 [Obsolete("Use SupportingUtils.BuildArray directly")]
190 protected Array
GetResultsArray(Type t
, IList list
, bool distinct
)
192 return SupportingUtils
.BuildArray(t
, list
, distinct
);
196 /// Converts the results stored in an <see cref="IList"/> to an
197 /// strongly-typed array.
199 /// <param name="t">The type of the new array</param>
200 /// <param name="list">The source list</param>
201 /// <param name="entityIndex">
202 /// If the HQL clause selects more than one field, or a join is performed
203 /// without using <c>fetch join</c>, the contents of the result list will
204 /// be of type <c>object[]</c>. Specify which index in this array should be used to
205 /// compose the new result array. Use <c>-1</c> to ignore this parameter.
207 /// <param name="distinct">If true, only distinct results will be inserted in the array</param>
208 /// <returns>The strongly-typed array</returns>
209 [Obsolete("Use SupportingUtils.BuildArray directly")]
210 protected Array
GetResultsArray(Type t
, IList list
, int entityIndex
, bool distinct
)
212 return SupportingUtils
.BuildArray(t
, list
, entityIndex
, distinct
);
216 /// Gets the internal list of modifiers used by the specified query.
217 /// NOT INTENTED FOR NORMAL USE.
219 public static IList
GetModifiers(ActiveRecordBaseQuery query
)
221 return query
.queryModifiers
;