What a day. I'm trying to build an application that I may or may not try to make money off of in the future, but I'm being complicated by doing it in #fsharp and #SAFE, so the entire application from UI to backend is all in FSharp.

I lost a lot of time recently because I'm also getting back into #postgresql from the last few years in #mongodb #documentDatabases. It took a lot of time to get queries to work with jsonb columns. I gave up on jsonb[]. Couldn't get that to work at all.

I finally ran into an issue where I was using the DbFun library for some type-safe sql, where I could do something like

let findByIdQuery queryBuilder : DbQuery<int, User> = queryBuilder.Sql("select * from users where Id = @id") let findById id runner = findByIdQuery id |> runner.run

and it would be type checked as valid #SQL at build time.

But eventually, I had to give up on it because that lib, somehow, was demanding FSharp.Core v9, but the SAFE stack is only compatible with dotnet 8, so I had to downgrade everything. It was such a pain.

I gave up on that and am now just using Dapper and Dapper.FSharp, but I ran into an issue that I lost several hours to with the sql error of

column "id" is not found. Column "id" exists but cannot be used in this part of the query.

I lost so many hours to that. It turns out I made the record type for that query private(T . T)

Anyway, I eventually figured that out and the integration tests pass with ephemeral postgres containers. From there I moved on to fixing the bindings for a react carousel component that I had claude generate so that I could use the react component in FSharp.

But man, I've lost so much time just trying to do efficient db queries. I miss Mongo's ability to easily serialize custom types, discriminated unions, and handle upsertis with { IsUpsert = true }, and easily handle multiple objects at a time. Trying to do the same in #sql is kind of a nightmare.

I didn't want to make N queries to upsert records in a list, so after days of tinkering, I wound up making a custom type and function / stored proc to do the upsert.
In mongo I would have been done with zero time, because again, it handles custom types and { IsUpsert = true } is a life saver compared to the massive crap I'm writing in SQL. I hope my columns don't change any time soon.

I suppose I could have used a type provider / ORM and let it generate queries, but that could cost micro-seconds. MICRO-seconds!

I'm doing this to myself and I'm aware of it.

Replication is available on FerretDB v2, meaning your database stays available even when things go wrong.

What’s in it for you?

- High availability
- Disaster recovery
- Load distribution

Read more: https://buff.ly/4gvlYoJ

#FerretDB #Replication #OpenSource #DocumentDatabases

Replication in FerretDB: Enabling High Availability and Performance | FerretDB Blog

Learn how replication in FerretDB can help you create a reliable and fault-tolerant environment for your applications.