Last active
August 11, 2024 20:54
-
-
Save SCullman/8f1b5d1ff123f1b50797ee1ae3c60469 to your computer and use it in GitHub Desktop.
PetaPoco and F# Options
This file contains hidden or 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
namespace PetaPoco.FSharpOptions | |
open PetaPoco | |
open System | |
type OptionConverterAttribute() = | |
inherit ValueConverterAttribute() | |
with | |
override __.ConvertFromDb(value: obj) = | |
let toOption (v: 'T) = | |
(if (isNull v) then None else Some v) |> box | |
let nullableToOption (n: System.Nullable<_>) = | |
(if n.HasValue then | |
Some n.Value | |
else | |
None) | |
|> box | |
match value with | |
| :? string as s -> toOption s | |
| :? (Nullable<char>) as c -> nullableToOption c | |
| :? (Nullable<bool>) as i -> nullableToOption i | |
| :? (Nullable<int>) as i -> nullableToOption i | |
| :? (Nullable<uint>) as i -> nullableToOption i | |
| :? (Nullable<int64>) as i -> nullableToOption i | |
| :? (Nullable<float>) as i -> nullableToOption i | |
| :? (Nullable<float32>) as i -> nullableToOption i | |
| :? (Nullable<decimal>) as i -> nullableToOption i | |
| :? (Nullable<DateTime>) as i -> nullableToOption i | |
| :? (Nullable<DateTimeOffset>) as i -> nullableToOption i | |
| :? (Nullable<Guid>) as i -> nullableToOption i | |
| _ -> failwith "Converter not implemented" | |
override __.ConvertToDb(value: obj) = | |
let nullOrValue v = | |
match v with | |
| Some v -> box v | |
| _ -> null | |
match value with | |
| :? (Option<string>) as v -> nullOrValue v | |
| :? (Option<char>) as v -> nullOrValue v | |
| :? (Option<bool>) as v -> nullOrValue v | |
| :? (Option<int>) as v -> nullOrValue v | |
| :? (Option<uint>) as v -> nullOrValue v | |
| :? (Option<int64>) as v -> nullOrValue v | |
| :? (Option<float>) as v -> nullOrValue v | |
| :? (Option<float32>) as v -> nullOrValue v | |
| :? (Option<decimal>) as v -> nullOrValue v | |
| :? (Option<DateTime>) as v -> nullOrValue v | |
| :? (Option<DateTimeOffset>) as v -> nullOrValue v | |
| :? (Option<Guid>) as v -> nullOrValue v | |
| _ -> failwith "Converter not implemented" | |
type OptionMapper() = | |
inherit PetaPoco.StandardMapper() | |
let isOption (p: System.Reflection.PropertyInfo) = | |
p.PropertyType.IsGenericType | |
&& p.PropertyType.GetGenericTypeDefinition() = typedefof<Option<_>> | |
override __.GetFromDbConverter | |
( | |
targetProperty: System.Reflection.PropertyInfo, | |
sourceType: System.Type | |
): System.Func<obj, obj> = | |
if (isOption targetProperty) then | |
System.Func<obj, obj>(OptionConverterAttribute().ConvertFromDb) | |
else | |
null | |
override __.GetToDbConverter(sourceProperty: System.Reflection.PropertyInfo): System.Func<obj, obj> = | |
if (isOption sourceProperty) then | |
System.Func<obj, obj>(OptionConverterAttribute().ConvertToDb) | |
else | |
null |
This file contains hidden or 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
[<CLIMutable>] | |
type T = | |
{ Id: int | |
Text: string option | |
Integer: int option | |
Date: DateTime option } | |
//the mapper is always for the "class" | |
PetaPoco.Mappers.Register(typeof<T>, OptionMapper()) |> ignore | |
let db = new PetaPoco.Database("petapoco") | |
let t = { Id =22; Text =Some "22" ; Integer= None ; Date = None} | |
db.Insert t |> ignore | |
let ts = db.Fetch<T>() |> Seq.toList |
This file contains hidden or 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
[<CLIMutable>] | |
type T = | |
{ Id: int | |
[<OptionConverter>] | |
Text: string option | |
[<OptionConverter>] | |
Integer: int option | |
[<OptionConverter>] | |
Date: DateTime option } | |
let db = new PetaPoco.Database("petapoco") | |
let t = { Id =22; Text =Some "22" ; Integer= None ; Date = None} | |
db.Insert t |> ignore | |
let ts = db.Fetch<T>() |> Seq.toList |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment