Donald
Donald copied to clipboard
How to deal with DB enums in Donald?
Hi, I am using Donald with Postgres, where I have a Logs table with one of the columns being a postgres enum. I'm not too sure how to read this properly with Donald.
Here is the sql:
CREATE TYPE "LogLevel" AS ENUM ('Trace', 'Debug', 'Information', 'Warning', 'Error', 'Critical');
CREATE TABLE "Logs" (
"uniqueId" UUID NOT NULL DEFAULT gen_random_uuid(),
"createdAt" DOUBLE PRECISION NOT NULL,
"level" "LogLevel" NOT NULL,
"message" TEXT,
"service" TEXT,
"error" TEXT,
"other" TEXT,
CONSTRAINT "Logs_pkey" PRIMARY KEY ("uniqueId")
);
Here is my F# type for a Log:
module RidoModels
type LogLevel =
| Trace = 1
| Debug = 2
| Information = 3
| Warning = 4
| Error = 5
| Critical = 6
[<CLIMutable>]
type Log =
{ uniqueId: string
createdAt: double
level: LogLevel
message: Option<string>
service: Option<string>
error: Option<string>
other: Option<string> }
Here is my F# DB code:
module DB.DB
open System.Data
open Donald
open Npgsql
open System
let conn =
new NpgsqlConnection(Environment.GetEnvironmentVariable("DOTNET_DB_CONNECTION_STRING"))
:> IDbConnection
module Log =
let ofDataReader (rd: IDataReader) : RidoModels.Log =
{ uniqueId = rd.ReadString "uniqueId"
createdAt = rd.ReadDouble "createdAt"
level = rd.ReadString "level"
message = rd.ReadStringOption "message"
service = rd.ReadStringOption "service"
error = rd.ReadStringOption "error"
other = rd.ReadStringOption "other" }
The compiler complains about a type mismach for the level = rd.ReadString "level" line:
Type constraint mismatch. The type
'string'
is not compatible with type
'RidoModels.LogLevel'
So how would I go about dealing with an DB enum in Donald?
Apologies, doing the best I can to manage my OSS as the business in my life goes up.
This is a good question. I don't use postgres, so my ability to test is limited. BUT! I would solve this by reading the value in raw as an obj and parse it. Something like:
module LogLevel =
let parse (level : obj) =
// ...
// meanwhile in your `Log` module...
level = rd.GetOrdinal("level") |> rd.GetValue |> LogLevel.parse