Skip to content

Instantly share code, notes, and snippets.

@MatthewVines
Last active August 29, 2015 14:14
Show Gist options
  • Save MatthewVines/69cebb80c88441e623f7 to your computer and use it in GitHub Desktop.
Save MatthewVines/69cebb80c88441e623f7 to your computer and use it in GitHub Desktop.
Mapper for NodaTime types for peta poco and npoco
using System;
using NodaTime;
using NPoco;
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;
//Added To make the damn thing work.
//Todo: figure out how destType actually works.
return ((Instant)x).ToDateTimeOffset();
};
}
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