Created
December 31, 2015 08:59
-
-
Save chilversc/d1ba1fdbae58d8a13704 to your computer and use it in GitHub Desktop.
NHibernate NodaTime.OffsetDateTime
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Data; | |
using NHibernate; | |
using NHibernate.SqlTypes; | |
using NHibernate.UserTypes; | |
using NodaTime; | |
[Serializable] | |
public class InstantType : IUserType | |
{ | |
public SqlType[] SqlTypes | |
{ | |
get { return new[] {SqlTypeFactory.DateTime}; } | |
} | |
public Type ReturnedType | |
{ | |
get { return typeof (Instant); } | |
} | |
public bool IsMutable | |
{ | |
get { return false; } | |
} | |
public new bool Equals (object x, object y) | |
{ | |
return object.Equals (x, y); | |
} | |
public int GetHashCode (object x) | |
{ | |
return x == null ? 0 : x.GetHashCode (); | |
} | |
public object NullSafeGet (IDataReader rs, string[] names, object owner) | |
{ | |
var value = NHibernateUtil.DateTime.NullSafeGet (rs, names); | |
if (value == null) | |
return null; | |
else | |
return Instant.FromDateTimeUtc (DateTime.SpecifyKind((DateTime) value, DateTimeKind.Utc)); | |
} | |
public void NullSafeSet (IDbCommand cmd, object value, int index) | |
{ | |
if (value == null) | |
NHibernateUtil.DateTime.NullSafeSet (cmd, null, index); | |
else | |
NHibernateUtil.DateTime.NullSafeSet (cmd, ((Instant) value).ToDateTimeUtc (), index); | |
} | |
public object DeepCopy (object value) | |
{ | |
return value; | |
} | |
public object Replace (object original, object target, object owner) | |
{ | |
return original; | |
} | |
public object Assemble (object cached, object owner) | |
{ | |
return cached; | |
} | |
public object Disassemble (object value) | |
{ | |
return value; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using NHibernate.Linq.Functions; | |
// Use configuration.LinqToHqlGeneratorsRegistry<LinqToHqlGeneratorsRegistry> () to register this | |
public class LinqToHqlGeneratorsRegistry : DefaultLinqToHqlGeneratorsRegistry | |
{ | |
public LinqToHqlGeneratorsRegistry() | |
{ | |
this.Merge (new OffsetDateTimeToInstantGenerator ()); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections.ObjectModel; | |
using System.Linq.Expressions; | |
using System.Reflection; | |
using NHibernate.Hql.Ast; | |
using NHibernate.Linq; | |
using NHibernate.Linq.Functions; | |
using NHibernate.Linq.Visitors; | |
using NodaTime; | |
// Converts OffsetDateTime.ToInstant() to use the OffsetDateTimeType's UtcDateTime property | |
// e.g. items.Where(x => x.Date.ToInstant() > minDate.ToInstant()) | |
// is converted to the HQL; WHERE x.UtcDateTime > @minDate | |
public class OffsetDateTimeToInstantGenerator : BaseHqlGeneratorForMethod | |
{ | |
public OffsetDateTimeToInstantGenerator() | |
{ | |
SupportedMethods = new [] { | |
ReflectionHelper.GetMethodDefinition<OffsetDateTime> (x => x.ToInstant()) | |
}; | |
} | |
public override HqlTreeNode BuildHql(MethodInfo method, Expression targetObject, ReadOnlyCollection<Expression> arguments, HqlTreeBuilder treeBuilder, IHqlExpressionVisitor visitor) | |
{ | |
var source = visitor.Visit (targetObject).AsExpression (); | |
var property = treeBuilder.Ident ("UtcDateTime"); | |
return treeBuilder.Dot (source, property); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Data; | |
using NHibernate; | |
using NHibernate.Engine; | |
using NHibernate.Type; | |
using NHibernate.UserTypes; | |
using NodaTime; | |
[Serializable] | |
public class OffsetDateTimeType : ICompositeUserType | |
{ | |
private static readonly IType instantType = NHibernateUtil.Custom (typeof (InstantType)); | |
private static readonly IType offsetType = NHibernateUtil.Custom (typeof (OffsetType)); | |
// UtcDateTime will be available as a property for HQL queries | |
public string[] PropertyNames | |
{ | |
get { return new[] {"UtcDateTime", "Offset"}; } | |
} | |
public IType[] PropertyTypes | |
{ | |
get { return new[] {instantType, offsetType}; } | |
} | |
public Type ReturnedClass | |
{ | |
get { return typeof (OffsetDateTime); } | |
} | |
public bool IsMutable | |
{ | |
get { return false; } | |
} | |
public object GetPropertyValue (object component, int property) | |
{ | |
var date = (OffsetDateTime) component; | |
switch (property) { | |
case 0: return date.ToInstant (); | |
case 1: return date.Offset; | |
default: throw new ArgumentOutOfRangeException ("property"); | |
} | |
} | |
public void SetPropertyValue (object component, int property, object value) | |
{ | |
throw new NotSupportedException ("OffsetDateTime is immutable"); | |
} | |
public new bool Equals (object x, object y) | |
{ | |
if (x == null && y == null) return true; | |
if (x == null || y == null) return false; | |
return ((OffsetDateTime) x).ToInstant () == ((OffsetDateTime) y).ToInstant (); | |
} | |
public int GetHashCode (object x) | |
{ | |
return x == null ? 0 : ((OffsetDateTime) x).ToInstant ().GetHashCode (); | |
} | |
public object NullSafeGet (IDataReader dr, string[] names, ISessionImplementor session, object owner) | |
{ | |
var utc = (Instant?) instantType.NullSafeGet (dr, names [0], session, owner); | |
var offset = (Offset?) offsetType.NullSafeGet (dr, names [1], session, owner); | |
if (utc == null) | |
return null; | |
else | |
return utc.Value.WithOffset (offset ?? Offset.Zero); | |
} | |
public void NullSafeSet (IDbCommand cmd, object value, int index, bool[] settable, ISessionImplementor session) | |
{ | |
if (value == null) { | |
instantType.NullSafeSet (cmd, null, index, session); | |
offsetType.NullSafeSet (cmd, null, index + 1, session); | |
} else { | |
var date = (OffsetDateTime) value; | |
instantType.NullSafeSet (cmd, date.ToInstant (), index, session); | |
offsetType.NullSafeSet (cmd, date.Offset, index + 1, session); | |
} | |
} | |
public object DeepCopy (object value) | |
{ | |
return value; | |
} | |
public object Disassemble (object value, ISessionImplementor session) | |
{ | |
return value; | |
} | |
public object Assemble (object cached, ISessionImplementor session, object owner) | |
{ | |
return cached; | |
} | |
public object Replace (object original, object target, ISessionImplementor session, object owner) | |
{ | |
return original; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Data; | |
using NHibernate; | |
using NHibernate.SqlTypes; | |
using NHibernate.UserTypes; | |
using NodaTime; | |
[Serializable] | |
public class OffsetType : IUserType | |
{ | |
public SqlType[] SqlTypes | |
{ | |
get { return new[] {SqlTypeFactory.Int16}; } | |
} | |
public Type ReturnedType | |
{ | |
get { return typeof (Offset); } | |
} | |
public bool IsMutable | |
{ | |
get { return false; } | |
} | |
public new bool Equals (object x, object y) | |
{ | |
return object.Equals (x, y); | |
} | |
public int GetHashCode (object x) | |
{ | |
return x == null ? 0 : x.GetHashCode (); | |
} | |
public object NullSafeGet (IDataReader rs, string[] names, object owner) | |
{ | |
var value = NHibernateUtil.Int16.NullSafeGet (rs, names); | |
if (value == null) | |
return null; | |
else | |
return OffsetFromMinutes ((short) value); | |
} | |
public void NullSafeSet (IDbCommand cmd, object value, int index) | |
{ | |
if (value == null) | |
NHibernateUtil.Int16.NullSafeSet (cmd, null, index); | |
else | |
NHibernateUtil.Int16.NullSafeSet (cmd, OffsetToMinutes ((Offset) value), index); | |
} | |
public object DeepCopy (object value) | |
{ | |
return value; | |
} | |
public object Replace (object original, object target, object owner) | |
{ | |
return original; | |
} | |
public object Assemble (object cached, object owner) | |
{ | |
return cached; | |
} | |
public object Disassemble (object value) | |
{ | |
return value; | |
} | |
private static Offset OffsetFromMinutes (long value) | |
{ | |
return Offset.FromTicks (value * NodaConstants.TicksPerMinute); | |
} | |
private static short OffsetToMinutes (Offset value) | |
{ | |
return checked ((short) (value.Ticks / NodaConstants.TicksPerMinute)); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment