Created
January 15, 2014 07:59
-
-
Save mattjohnsonpint/8432461 to your computer and use it in GitHub Desktop.
NPoco mapper for NodaTime
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 NodaTime; | |
using NPoco; | |
namespace PocoNoda | |
{ | |
public class NodaMapper : DefaultMapper | |
{ | |
public override Func<object, object> GetFromDbConverter(Type DestType, Type SourceType) | |
{ | |
if (DestType == typeof(Instant) || DestType == typeof(Instant?)) | |
{ | |
return x => | |
{ | |
if (x == null) | |
return null; | |
// You can store as a DATETIMEOFFSET with zero offset | |
if (x is DateTimeOffset) | |
return Instant.FromDateTimeOffset((DateTimeOffset) x); | |
// Or, you can store as a DATETIME or DATETIME2 and just use UTC by convention | |
if (x is DateTime) | |
return Instant.FromDateTimeUtc(DateTime.SpecifyKind((DateTime) x, DateTimeKind.Utc)); | |
return x; | |
}; | |
} | |
if (DestType == typeof(OffsetDateTime) || DestType == typeof(OffsetDateTime?)) | |
{ | |
return x => | |
{ | |
if (x == null) | |
return null; | |
// store as a DATETIMEOFFSET | |
if (x is DateTimeOffset) | |
return OffsetDateTime.FromDateTimeOffset((DateTimeOffset)x); | |
return x; | |
}; | |
} | |
if (DestType == typeof(LocalDateTime) || DestType == typeof(LocalDateTime?)) | |
{ | |
return x => | |
{ | |
if (x == null) | |
return null; | |
// This can be stored as a DATETIME or DATETIME2 | |
if (x is DateTime) | |
return LocalDateTime.FromDateTime((DateTime) x); | |
return x; | |
}; | |
} | |
if (DestType == typeof(LocalDate) || DestType == typeof(LocalDate?)) | |
{ | |
return x => | |
{ | |
if (x == null) | |
return null; | |
// store using a DATE type in SQL | |
if (x is DateTime) | |
return LocalDateTime.FromDateTime((DateTime)x).Date; | |
return x; | |
}; | |
} | |
if (DestType == typeof(LocalTime) || DestType == typeof(LocalTime?)) | |
{ | |
return x => | |
{ | |
if (x == null) | |
return null; | |
// store using a TIME type in SQL | |
if (x is TimeSpan) | |
return LocalTime.FromTicksSinceMidnight(((TimeSpan)x).Ticks); | |
return x; | |
}; | |
} | |
if (DestType == typeof(Duration) || DestType == typeof(Duration?)) | |
{ | |
return x => | |
{ | |
if (x == null) | |
return null; | |
// You can use a TIME type in SQL, but it's going to be limited to less than 24 hours. | |
if (x is TimeSpan) | |
return Duration.FromTimeSpan((TimeSpan) x); | |
// If stored as 32-bit integer, you'll need to set the precision. | |
// Here, it's using seconds. | |
if (x is int) | |
return Duration.FromSeconds((int) x); | |
// For full storage of a Duration, you'll need to store as a 64-bit integer. | |
if (x is long) | |
return Duration.FromTicks((long) x); | |
return x; | |
}; | |
} | |
return base.GetFromDbConverter(DestType, SourceType); | |
} | |
public override Func<object, object> GetToDbConverter(Type DestType, Type SourceType) | |
{ | |
if (SourceType == typeof(Instant) || SourceType == typeof(Instant?)) | |
{ | |
return x => | |
{ | |
if (x == null) | |
return null; | |
// You can store as a DATETIMEOFFSET with zero offset | |
if (DestType == typeof (DateTimeOffset) || DestType == typeof (DateTimeOffset?)) | |
return ((Instant) x).ToDateTimeOffset(); | |
// Or, you can store as a DATETIME or DATETIME2 and just use UTC by convention | |
if (DestType == typeof(DateTime) || DestType == typeof(DateTime?)) | |
return ((Instant) x).ToDateTimeUtc(); | |
return x; | |
}; | |
} | |
if (SourceType == typeof(OffsetDateTime) || SourceType == typeof(OffsetDateTime?)) | |
{ | |
return x => | |
{ | |
if (x == null) | |
return null; | |
// store as a DATETIMEOFFSET | |
if (DestType == typeof(DateTimeOffset) || DestType == typeof(DateTimeOffset?)) | |
return ((OffsetDateTime)x).ToDateTimeOffset(); | |
return x; | |
}; | |
} | |
if (SourceType == typeof(LocalDateTime) || SourceType == typeof(LocalDateTime?)) | |
{ | |
return x => | |
{ | |
if (x == null) | |
return null; | |
// This can be stored as a DATETIME or DATETIME2 | |
if (DestType == typeof (DateTime) || DestType == typeof (DateTime?)) | |
return ((LocalDateTime) x).ToDateTimeUnspecified(); | |
return x; | |
}; | |
} | |
if (SourceType == typeof(LocalDate) || SourceType == typeof(LocalDate?)) | |
{ | |
return x => | |
{ | |
if (x == null) | |
return null; | |
// store using a DATE type in SQL | |
if (DestType == typeof(DateTime) || DestType == typeof(DateTime?)) | |
return ((LocalDate)x).AtMidnight().ToDateTimeUnspecified(); | |
return x; | |
}; | |
} | |
if (SourceType == typeof(LocalTime) || SourceType == typeof(LocalTime?)) | |
{ | |
return x => | |
{ | |
if (x == null) | |
return null; | |
// store using a TIME type in SQL | |
if (DestType == typeof (TimeSpan) || DestType == typeof (TimeSpan?)) | |
return TimeSpan.FromTicks(((LocalTime) x).TickOfDay); | |
return x; | |
}; | |
} | |
if (SourceType == typeof(Duration) || SourceType == typeof(Duration?)) | |
{ | |
return x => | |
{ | |
if (x == null) | |
return null; | |
// You can use a TIME type in SQL, but it's going to be limited to less than 24 hours. | |
if (DestType == typeof (TimeSpan) || DestType == typeof (TimeSpan?)) | |
return ((Duration) x).ToTimeSpan(); | |
// If stored as 32-bit integer, you'll need to set the precision. | |
// Here, it's using seconds. | |
if (DestType == typeof (int) || DestType == typeof (int?)) | |
return (int) ((Duration) x).ToTimeSpan().TotalSeconds; | |
// For full storage of a Duration, you'll need to store as a 64-bit integer. | |
if (DestType == typeof(long) || DestType == typeof(long?)) | |
return ((Duration)x).Ticks; | |
return x; | |
}; | |
} | |
return base.GetToDbConverter(DestType, SourceType); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment