|
using System;
using System.Data;
using NHibernate;
using NHibernate.SqlTypes;
using NHibernate.UserTypes;
using Parichay.Security.Helper;
namespace Parichay.Security.UserType
{
/// <summary>
/// NHibernate data type to handle Oracle representation of a boolean, which is mainly <c>CHAR(1)</c>.
/// </summary>
/// <remarks>
/// <p>This implementation is neceassary to avoid an exception thrown by <see cref="bool.Parse"/> since it does not know
/// how to handle <c>1</c> or <c>0</c> and boolean values. The implementation is only required for the <see cref="NullSafeGet"/>
/// method. Therefore, the remainder of the class delegates to the <see cref="NHibernateUtil.Boolean"/> instance.</p>
/// <p>An alternative to using a user type to circumvent this problem is to simply use <c>NUMBER(1,0)</c> instead of <c>CHAR(1)</c>
/// when defining a column in Oracle to represent a boolean.</p>
/// </remarks>
[Serializable]
public class OneZeroType : IUserType
{
#region IUserType Implementation
/// <summary>
/// The SQL types for the columns mapped by this type.
/// </summary>
public SqlType[] SqlTypes
{
get { return new SqlType[] { NHibernateUtil.Boolean.SqlType }; }
}
/// <summary>
/// The type returned by <see cref="NullSafeGet"/>.
/// </summary>
public Type ReturnedType
{
get { return typeof(bool); }
}
/// <summary>
/// Compare two instances of the class mapped by this type for persistent "equality"
/// ie. equality of persistent state.
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <returns></returns>
public new bool Equals(object x, object y)
{
return (x == y);
}
/// <summary>
/// Get a hashcode for the instance, consistent with persistence "equality"
/// </summary>
/// <remarks>Required for NHibernate 1.2 Beta 2.</remarks>
public int GetHashCode(object obj)
{
return ((null == obj) ? GetHashCode() : obj.GetHashCode());
}
/// <summary>
/// Retrieve an instance of the mapped class from a result set.
/// </summary>
/// <remarks>Implementors should handle possibility of null values.</remarks>
/// <param name="rs">result set containing the data to evaluate.</param>
/// <param name="names">column names.</param>
/// <param name="owner">the containing entity.</param>
/// <returns></returns>
/// <exception cref="HibernateException">HibernateException</exception>
/// <exception cref="System.Data.SqlClient.SqlException">SqlException</exception>
public object NullSafeGet(IDataReader rs, string[] names, object owner)
{
object val = null;
int index = rs.GetOrdinal(names[0]);
if (!rs.IsDBNull(index))
{
try
{
val = rs[index];
val = ("1".Equals(val) ? true : ("0".Equals(val) ? false : NHibernateUtil.Boolean.Get(rs, index)));
}
catch (InvalidCastException ex)
{
throw new ADOException(
"Could not cast the value in field " + names[0] + " of type " + rs[index].GetType().Name + " to the Type " + GetType().Name +
". Please check to make sure that the mapping is correct and that your DataProvider supports this Data Type.", ex);
}
}
return val;
}
/// <summary>
/// Write an instance of the mapped class to a prepared statement.
/// </summary>
/// <remarks>
/// Implementors should handle possibility of <c>null</c> values. A multi-column type should be written
/// to parameters starting from <paramref name="index"/>.
/// </remarks>
/// <param name="cmd">a IDbCommand</param>
/// <param name="value">the object to write</param>
/// <param name="index">command parameter index</param>
/// <exception cref="HibernateException">HibernateException</exception>
/// <exception cref="System.Data.SqlClient.SqlException">SqlException</exception>
public void NullSafeSet(IDbCommand cmd, object value, int index)
{
NHibernateUtil.Boolean.NullSafeSet(cmd, value, index);
}
/// <summary>
/// Return a deep copy of the persistent state, stopping at entities and at collections.
/// </summary>
/// <param name="value">generally a collection element or entity field.</param>
/// <returns>a copy.</returns>
public object DeepCopy(object value)
{
return NHibernateUtil.Boolean.DeepCopy(value, EntityMode.Map,
NHibernateHelper.GetCurrentSession().GetSessionImplementation().Factory);
}
/// <summary>
/// Are objects of this type mutable?
/// </summary>
public bool IsMutable
{
get { return NHibernateUtil.Boolean.IsMutable; }
}
/// <summary>
/// During merge, replace the existing (<paramref name="target" />) value in the entity
/// we are merging to with a new (<paramref name="original" />) value from the detached
/// entity we are merging. For immutable objects, or null values, it is safe to simply
/// return the first parameter. For mutable objects, it is safe to return a copy of the
/// first parameter. For objects with component values, it might make sense to
/// recursively replace component values.
/// </summary>
/// <param name="original">the value from the detached entity being merged</param>
/// <param name="target">the value in the managed entity</param>
/// <param name="owner">the managed entity</param>
/// <returns>the value to be merged</returns>
public object Replace(object original, object target, object owner)
{
return DeepCopy(original);
}
/// <summary>
/// Reconstruct an object from the cacheable representation. At the very least this
/// method should perform a deep copy if the type is mutable. (optional operation)
/// </summary>
/// <param name="cached">the object to be cached</param>
/// <param name="owner">the owner of the cached object</param>
/// <returns>a reconstructed object from the cachable representation</returns>
public object Assemble(object cached, object owner)
{
return DeepCopy(cached);
}
/// <summary>
/// Transform the object into its cacheable representation. At the very least this
/// method should perform a deep copy if the type is mutable. That may not be enough
/// for some implementations, however; for example, associations must be cached as
/// identifier values. (optional operation)
/// </summary>
/// <param name="value">the object to be cached</param>
/// <returns>a cacheable representation of the object</returns>
public object Disassemble(object value)
{
return DeepCopy(value);
}
#endregion IUserType Implementation
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
I love programming, reading, and meditation. I like to explore management and productivity.