I'm trying to use the hello-world example from the roc postgres client, but compilation gives this error
── UNKNOWN OPERATOR in src/../roc-pg/src/Pg/Client.roc ─────────────────────────
This looks like an operator, but it's not one I recognize!
39│ stream <- Tcp.withConnect host port
^^
I have no specific suggestion for this operator, see
I'm using nightly-roc, so maybe that is the problem?
roc nightly pre-release, built from commit c47a8e9 on Sa 22 Mär 2025 09:02:05 UTC
That is the backpassing operator which has been removed from the language. I think roc-pg will need to be substantially refactored to be compiled again
okay thanks for the explanation. is there any sql client library available for roc?
Sorry @Don P I don't think there is any right now.
There is SQLite in basic webserver
Yeah, I was thinking of cross-platform libraries. The SQlite in basic-cli and basic-webserver work nice imo
I've left an issue on the roc-pg repo asking for the latest version it did compile for. It looks like the project has been idle for a year. For my purposes I can export some data from psql into sqlite for playing around with roc. thanks.
@Agus Zubiaga was instrumental with the design and evolution of the map-2 record builders, which enables a really nice API for sql clients and is much simpler than the backpassing approach or the other record builders API we have before map-2 based ones.
I'm sure he'll be keen to upgrade the package as soon as we have the new compiler online as it's a super cool API and very unique to roc. I don't know of any other language that will have as nice a story for working with sql as roc 0.1 :heart_eyes: (but I may be biased a little)
For reference, this is an example of the record builder API from basic-cli
query_todos_by_status! : Str, Str => Result (List Todo) (Sqlite.SqlDecodeErr _)
query_todos_by_status! = |db_path, status|
Sqlite.query_many!(
{
path: db_path,
query: "SELECT id, task, status FROM todos WHERE status = :status;",
bindings: [{ name: ":status", value: String(status) }],
rows: { Sqlite.decode_record <-
id: Sqlite.i64("id") |> Sqlite.map_value(Num.to_str),
task: Sqlite.str("task"),
status: Sqlite.str("status") |> Sqlite.map_value_result(decode_todo_status),
},
},
)
I posted a PR for migrating to the new syntax, but it's incomplete as I didn't touch the query builder and it may contain choices which Agus would make differently. I couldn't live without roc-pg
in my life, though, so I created a fork with releases here: https://github.com/growthagent/roc-pg
I'll retire the fork once roc-pg
is back in action, but it's fine to use for now if you'd like. Note that I've made some unholy changes that may or may not make it into roc-pg
, like how record builders work now and I've introduced Maybe
for nullable input and outputs. Here's a full example: https://github.com/growthagent/roc-pg/blob/main/examples/query-with-record-builder.roc
Happy paddling!
Hey all! I'm not quite back in action, but I did publish roc-pg@0.1.1
with @Niclas Ahden's migration (thx so much :heart:).
I've decided to remove the query builder from main
as I never quite got it over the line, and I don't have the time to dedicate to it. I'd love to return to it when the new compiler is out, and things are calmer in my life.
Last updated: Jul 05 2025 at 12:14 UTC