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 NHibernate
.Expressions
;
21 using Castle
.ActiveRecord
.Framework
;
24 /// Allow programmers to use the
25 /// ActiveRecord functionality without direct reference
26 /// to <see cref="ActiveRecordBase"/>
28 public class ActiveRecordMediator
31 /// Invokes the specified delegate passing a valid
32 /// NHibernate session. Used for custom NHibernate queries.
34 /// <param name="targetType">The target ActiveRecordType</param>
35 /// <param name="call">The delegate instance</param>
36 /// <param name="instance">The ActiveRecord instance</param>
37 /// <returns>Whatever is returned by the delegate invocation</returns>
38 public static object Execute(Type targetType
, NHibernateDelegate call
, object instance
)
40 return ActiveRecordBase
.Execute(targetType
, call
, instance
);
44 /// Finds an object instance by its primary key.
46 /// <param name="targetType">The AR subclass type</param>
47 /// <param name="id">ID value</param>
48 /// <param name="throwOnNotFound"><c>true</c> if you want an exception to be thrown
49 /// if the object is not found</param>
50 /// <exception cref="ObjectNotFoundException">if <c>throwOnNotFound</c> is set to
51 /// <c>true</c> and the row is not found</exception>
52 public static object FindByPrimaryKey(Type targetType
, object id
, bool throwOnNotFound
)
54 return ActiveRecordBase
.FindByPrimaryKey(targetType
, id
, throwOnNotFound
);
58 /// Finds an object instance by its primary key.
60 /// <param name="targetType">The AR subclass type</param>
61 /// <param name="id">ID value</param>
62 public static object FindByPrimaryKey(Type targetType
, object id
)
64 return FindByPrimaryKey(targetType
, id
, true);
68 /// Searches and returns the first row.
70 /// <param name="targetType">The target type</param>
71 /// <param name="orders">The sort order - used to determine which record is the first one</param>
72 /// <param name="criterias">The criteria expression</param>
73 /// <returns>A <c>targetType</c> instance or <c>null</c></returns>
74 public static object FindFirst(Type targetType
, Order
[] orders
, params ICriterion
[] criterias
)
76 return ActiveRecordBase
.FindFirst(targetType
, orders
, criterias
);
80 /// Searches and returns the first row.
82 /// <param name="targetType">The target type</param>
83 /// <param name="criterias">The criteria expression</param>
84 /// <returns>A <c>targetType</c> instance or <c>null</c></returns>
85 public static object FindFirst(Type targetType
, params ICriterion
[] criterias
)
87 return FindFirst(targetType
, null, criterias
);
91 /// Searches and returns the first row.
93 /// <param name="targetType">The target type.</param>
94 /// <param name="detachedCriteria">The criteria.</param>
95 /// <param name="orders">The sort order - used to determine which record is the first one.</param>
96 /// <returns>A <c>targetType</c> instance or <c>null.</c></returns>
97 public static object FindFirst(Type targetType
, DetachedCriteria detachedCriteria
, params Order
[] orders
)
99 return ActiveRecordBase
.FindFirst(targetType
, detachedCriteria
, orders
);
103 /// Searches and returns the first row.
105 /// <param name="targetType">The target type</param>
106 /// <param name="criteria">The criteria expression</param>
107 /// <returns>A <c>targetType</c> instance or <c>null</c></returns>
108 public static object FindFirst(Type targetType
, DetachedCriteria criteria
)
110 return ActiveRecordBase
.FindFirst(targetType
, criteria
);
114 /// Searches and returns the a row. If more than one is found,
115 /// throws <see cref="ActiveRecordException"/>
117 /// <param name="targetType">The target type</param>
118 /// <param name="criterias">The criteria expression</param>
119 /// <returns>A <c>targetType</c> instance or <c>null</c></returns>
120 public static object FindOne(Type targetType
, params ICriterion
[] criterias
)
122 return ActiveRecordBase
.FindOne(targetType
, criterias
);
126 /// Searches and returns a row. If more than one is found,
127 /// throws <see cref="ActiveRecordException"/>
129 /// <param name="targetType">The target type</param>
130 /// <param name="criteria">The criteria</param>
131 /// <returns>A <c>targetType</c> instance or <c>null</c></returns>
132 protected internal static object FindOne(Type targetType
, DetachedCriteria criteria
)
134 return ActiveRecordBase
.FindOne(targetType
, criteria
);
138 /// Returns a portion of the query results (sliced)
140 public static Array
SlicedFindAll(Type targetType
, int firstResult
, int maxresults
,
141 Order
[] orders
, params ICriterion
[] criterias
)
143 return ActiveRecordBase
.SlicedFindAll(targetType
, firstResult
,
144 maxresults
, orders
, criterias
);
148 /// Returns a portion of the query results (sliced)
150 public static Array
SlicedFindAll(Type targetType
, int firstResult
, int maxresults
, params ICriterion
[] criterias
)
152 return SlicedFindAll(targetType
, firstResult
, maxresults
, null, criterias
);
156 /// Returns a portion of the query results (sliced)
158 public static Array
SlicedFindAll(Type targetType
, int firstResult
, int maxResults
,
159 Order
[] orders
, DetachedCriteria criteria
)
161 return ActiveRecordBase
.SlicedFindAll(targetType
, firstResult
, maxResults
, orders
, criteria
);
165 /// Returns a portion of the query results (sliced)
167 public static Array
SlicedFindAll(Type targetType
, int firstResult
, int maxResults
,
168 DetachedCriteria criteria
)
170 return ActiveRecordBase
.SlicedFindAll(targetType
, firstResult
, maxResults
, criteria
);
174 /// Returns all instances found for the specified type.
176 /// <param name="targetType"></param>
177 /// <returns></returns>
178 public static Array
FindAll(Type targetType
)
180 return FindAll(targetType
, (Order
[]) null);
184 /// Returns all instances found for the specified type
185 /// using sort orders and criterias.
187 /// <param name="targetType"></param>
188 /// <param name="orders"></param>
189 /// <param name="criterias"></param>
190 /// <returns></returns>
191 public static Array
FindAll(Type targetType
, Order
[] orders
, params ICriterion
[] criterias
)
193 return ActiveRecordBase
.FindAll(targetType
, orders
, criterias
);
197 /// Returns all instances found for the specified type
200 /// <param name="targetType"></param>
201 /// <param name="criterias"></param>
202 /// <returns></returns>
203 public static Array
FindAll(Type targetType
, params ICriterion
[] criterias
)
205 return FindAll(targetType
, null, criterias
);
209 /// Returns all instances found for the specified type according to the criteria
211 public static Array
FindAll(Type targetType
, DetachedCriteria detachedCriteria
, params Order
[] orders
)
213 return ActiveRecordBase
.FindAll(targetType
, detachedCriteria
, orders
);
217 /// Finds records based on a property value - automatically converts null values to IS NULL style queries.
219 /// <param name="targetType">The target type</param>
220 /// <param name="property">A property name (not a column name)</param>
221 /// <param name="value">The value to be equals to</param>
222 /// <returns></returns>
223 public static Array
FindAllByProperty(Type targetType
, String property
, object value)
225 return ActiveRecordBase
.FindAllByProperty(targetType
, property
, value);
229 /// Finds records based on a property value - automatically converts null values to IS NULL style queries.
231 /// <param name="targetType">The target type</param>
232 /// <param name="orderByColumn">The column name to be ordered ASC</param>
233 /// <param name="property">A property name (not a column name)</param>
234 /// <param name="value">The value to be equals to</param>
235 /// <returns></returns>
236 public static Array
FindAllByProperty(Type targetType
, String orderByColumn
, String property
, object value)
238 return ActiveRecordBase
.FindAllByProperty(targetType
, orderByColumn
, property
, value);
242 /// Deletes all entities of the specified type (and their inheritors)
244 /// <param name="type">The type.</param>
245 public static void DeleteAll(Type type
)
247 ActiveRecordBase
.DeleteAll(type
);
251 /// Deletes all entities of specified type that match the HQL where clause
253 /// <param name="type">The type.</param>
254 /// <param name="where">The where.</param>
255 public static void DeleteAll(Type type
, string where
)
257 ActiveRecordBase
.DeleteAll(type
, where
);
261 /// Deletes all <paramref name="targetType" /> objects, based on the primary keys
262 /// supplied on <paramref name="pkValues" />.
264 /// <param name="targetType">The target ActiveRecord type</param>
265 /// <param name="pkValues">A list of primary keys</param>
266 /// <returns>The number of objects deleted</returns>
267 public static int DeleteAll(Type targetType
, IEnumerable pkValues
)
269 return ActiveRecordBase
.DeleteAll(targetType
, pkValues
);
273 /// Enumerates the query.
274 /// Note: Only use if you expect most of the values to be on the second level cache
276 /// <param name="q">The query</param>
277 /// <returns></returns>
278 public static IEnumerable
EnumerateQuery(IActiveRecordQuery q
)
280 return ActiveRecordBase
.EnumerateQuery(q
);
284 /// Executes the query
286 /// <param name="q">The query</param>
287 /// <returns></returns>
288 public static object ExecuteQuery(IActiveRecordQuery q
)
290 return ActiveRecordBase
.ExecuteQuery(q
);
294 /// Returns the number of records of the specified
295 /// type in the database
300 /// public class User : ActiveRecordBase
304 /// public static int CountUsers()
306 /// return Count(typeof(User));
311 /// <param name="targetType">Type of the target.</param>
312 /// <returns>The count result</returns>
313 protected internal static int Count(Type targetType
)
315 return ActiveRecordBase
.Count(targetType
);
319 /// Returns the number of records of the specified
320 /// type in the database
325 /// public class User : ActiveRecordBase
329 /// public static int CountUsersLocked()
331 /// return Count(typeof(User), "IsLocked = ?", true);
336 /// <param name="targetType">Type of the target.</param>
337 /// <param name="filter">A sql where string i.e. Person=? and DOB > ?</param>
338 /// <param name="args">Positional parameters for the filter string</param>
339 /// <returns>The count result</returns>
340 public static int Count(Type targetType
, string filter
, params object[] args
)
342 return ActiveRecordBase
.Count(targetType
, filter
, args
);
346 /// Returns the number of records of the specified
347 /// type in the database
349 /// <param name="targetType">The target type.</param>
350 /// <param name="criteria">The criteria expression</param>
351 /// <returns>The count result</returns>
352 public static int Count(Type targetType
, params ICriterion
[] criteria
) {
353 return ActiveRecordBase
.Count(targetType
, criteria
);
357 /// Returns the number of records of the specified
358 /// type in the database
360 /// <param name="targetType">The target type.</param>
361 /// <param name="detachedCriteria">The criteria expression</param>
362 /// <returns>The count result</returns>
363 public static int Count(Type targetType
, DetachedCriteria detachedCriteria
)
365 return ActiveRecordBase
.Count(targetType
, detachedCriteria
);
369 /// Check if there is any records in the db for the target type
371 /// <param name="targetType">Type of the target.</param>
372 /// <returns><c>true</c> if there's at least one row</returns>
373 public static bool Exists(Type targetType
)
375 return ActiveRecordBase
.Exists(targetType
);
380 /// Check if there is any records in the db for the target type
382 /// <param name="targetType">Type of the target.</param>
383 /// <param name="filter">A sql where string i.e. Person=? and DOB > ?</param>
384 /// <param name="args">Positional parameters for the filter string</param>
385 /// <returns><c>true</c> if there's at least one row</returns>
386 public static bool Exists(Type targetType
, string filter
, params object[] args
)
388 return ActiveRecordBase
.Exists(targetType
, filter
, args
);
392 /// Check if the <paramref name="id"/> exists in the database.
394 /// <param name="targetType">Type of the target.</param>
395 /// <param name="id">The id to check on</param>
396 /// <returns><c>true</c> if the ID exists; otherwise <c>false</c>.</returns>
397 public static bool Exists(Type targetType
, object id
)
399 return ActiveRecordBase
.Exists(targetType
, id
);
403 /// Check if any instance matches the criteria.
405 /// <returns><c>true</c> if an instance is found; otherwise <c>false</c>.</returns>
406 public static bool Exists(Type targetType
, params ICriterion
[] criterias
)
408 return ActiveRecordBase
.Exists(targetType
, criterias
);
412 /// Check if any instance matching the criteria exists in the database.
414 /// <param name="targetType">The target type.</param>
415 /// <param name="detachedCriteria">The criteria expression</param>
416 /// <returns><c>true</c> if an instance is found; otherwise <c>false</c>.</returns>
417 public static bool Exists(Type targetType
, DetachedCriteria detachedCriteria
)
419 return ActiveRecordBase
.Exists(targetType
, detachedCriteria
);
423 /// Saves the instance to the database
425 /// <param name="instance">The ActiveRecord instance to be deleted</param>
426 public static void Save(object instance
)
428 ActiveRecordBase
.Save(instance
);
432 /// Saves the instance to the database and flushes the session. If the primary key is unitialized
433 /// it creates the instance on the database. Otherwise it updates it.
435 /// If the primary key is assigned, then you must invoke <see cref="Create(object)"/>
436 /// or <see cref="Update(object)"/> instead.
439 /// <param name="instance">The ActiveRecord instance to be saved</param>
440 public static void SaveAndFlush(object instance
)
442 ActiveRecordBase
.SaveAndFlush(instance
);
446 /// Saves a copy of instance to the database
448 /// <param name="instance">The transient instance to be copied</param>
449 /// <returns>The saved ActiveRecord instance</returns>
450 public static object SaveCopy(object instance
)
452 return ActiveRecordBase
.SaveCopy(instance
);
456 /// Saves a copy of the instance to the database and flushes the session. If the primary key is unitialized
457 /// it creates the instance on the database. Otherwise it updates it.
459 /// If the primary key is assigned, then you must invoke <see cref="Create(object)"/>
460 /// or <see cref="Update(object)"/> instead.
463 /// <param name="instance">The transient instance to be copied</param>
464 /// <returns>The saved ActiveRecord instance</returns>
465 public static void SaveCopyAndFlush(object instance
)
467 ActiveRecordBase
.SaveCopyAndFlush(instance
);
471 /// Creates (Saves) a new instance to the database.
473 /// <param name="instance">The ActiveRecord instance to be deleted</param>
474 public static void Create(object instance
)
476 ActiveRecordBase
.Create(instance
);
480 /// Creates (Saves) a new instance to the database and flushes the session.
482 /// <param name="instance">The ActiveRecord instance to be created on the database</param>
483 public static void CreateAndFlush(object instance
)
485 ActiveRecordBase
.CreateAndFlush(instance
);
489 /// Persists the modification on the instance
490 /// state to the database.
492 /// <param name="instance">The ActiveRecord instance to be deleted</param>
493 public static void Update(object instance
)
495 ActiveRecordBase
.Update(instance
);
499 /// Persists the modification on the instance
500 /// state to the database and flushes the session.
502 /// <param name="instance">The ActiveRecord instance to be updated on the database</param>
503 public static void UpdateAndFlush(object instance
)
505 ActiveRecordBase
.UpdateAndFlush(instance
);
509 /// Deletes the instance from the database.
511 /// <param name="instance">The ActiveRecord instance to be deleted</param>
512 public static void Delete(object instance
)
514 ActiveRecordBase
.Delete(instance
);
518 /// Deletes the instance from the database and flushes the session.
520 /// <param name="instance">The ActiveRecord instance to be deleted</param>
521 public static void DeleteAndFlush(object instance
)
523 ActiveRecordBase
.DeleteAndFlush(instance
);
527 /// Refresh the instance from the database.
529 /// <param name="instance">The ActiveRecord instance to be reloaded</param>
530 public static void Refresh(object instance
)
532 ActiveRecordBase
.Refresh(instance
);
536 /// Testing hock only.
538 public static ISessionFactoryHolder
GetSessionFactoryHolder()
540 return ActiveRecordBase
.holder
;
544 /// From NHibernate documentation:
545 /// Persist all reachable transient objects, reusing the current identifier
546 /// values. Note that this will not trigger the Interceptor of the Session.
548 /// <param name="instance">The instance.</param>
549 /// <param name="replicationMode">The replication mode.</param>
550 public static void Replicate(object instance
, ReplicationMode replicationMode
)
552 ActiveRecordBase
.Replicate(instance
, replicationMode
);
556 /// Evicts the specified instance from the first level cache (session level).
558 /// <param name="instance">The instance.</param>
559 public static void Evict(object instance
)
561 if (instance
== null) throw new ArgumentNullException("instance");
563 if (SessionScope
.Current
!= null)
565 SessionScope
.Current
.Evict(instance
);
570 /// Evicts the specified type.
572 /// <param name="type">The type.</param>
573 public static void GlobalEvict(Type type
)
575 if (type
== null) throw new ArgumentNullException("type");
577 ISessionFactory factory
= GetFactory(type
);
583 /// Evicts the specified type.
585 /// <param name="type">The type.</param>
586 /// <param name="id">The id.</param>
587 public static void GlobalEvict(Type type
, object id
)
589 if (type
== null) throw new ArgumentNullException("type");
591 ISessionFactory factory
= ActiveRecordBase
.holder
.GetSessionFactory(type
);
595 throw new ActiveRecordException("Could not find registered session factory for type " + type
.FullName
);
598 factory
.Evict(type
, id
);
601 private static ISessionFactory
GetFactory(Type type
)
603 ISessionFactory factory
= ActiveRecordBase
.holder
.GetSessionFactory(type
);
607 throw new ActiveRecordException("Could not find registered session factory for type " + type
.FullName
);