dream_postgres
PostgreSQL utilities for Gleam with type-safe query helpers.
A standalone module providing clean interfaces for PostgreSQL operations using Pog. Includes query result helpers and a builder pattern for connection management. Built with the same quality standards as Dream, but completely independent—use it in any Gleam project.
Features
- ✅ Builder pattern for connection configuration
- ✅ Type-safe query result extraction
- ✅ Simplified error handling
- ✅ Connection pooling via Pog
- ✅ Zero dependencies on Dream or other frameworks
Installation
gleam add dream_postgres
Quick Start
Connection Setup
import dream_postgres/client as postgres
import gleam/erlang/process
let pool_name = process.new_name("db_pool")
let assert Ok(db) = postgres.new(pool_name)
|> postgres.host("localhost")
|> postgres.port(5432)
|> postgres.database("myapp")
|> postgres.user("postgres")
|> postgres.password("secret")
|> postgres.pool_size(15)
|> postgres.connect()
Or from URL
import dream_postgres/client as postgres
let db = postgres.from_url("postgresql://user:pass@localhost:5432/myapp")
Query Execution
Use with Squirrel or Pog directly:
import dream_postgres/query
import user/sql // Your Squirrel-generated queries
// Get first row
case sql.get_user(db, id) |> query.first_row() {
Ok(user) -> decode_user(user)
Error(query.NotFound) -> handle_not_found()
Error(query.DatabaseError) -> handle_error()
}
// Get all rows
case sql.list_users(db) |> query.all_rows() {
Ok(users) -> list.map(users, decode_user)
Error(query.DatabaseError) -> handle_error()
}
Usage
Connection Builder Pattern
Configure your database connection step by step:
import dream_postgres/client as postgres
import gleam/erlang/process
let pool_name = process.new_name("my_db_pool")
let config = postgres.new(pool_name)
|> postgres.host("localhost")
|> postgres.port(5432)
|> postgres.database("myapp_prod")
|> postgres.user("postgres")
|> postgres.password("secret")
|> postgres.pool_size(20) // Max 20 connections
let assert Ok(db) = postgres.connect(config)
Query Result Helpers
The query module provides simple helpers for extracting data from Pog results:
import dream_postgres/query
// First row (for "get by ID" queries)
case sql.get_user(db, id) |> query.first_row() {
Ok(row) -> {
// Decode row to your type
decode_user(row)
}
Error(query.NotFound) -> {
// Query succeeded but no rows returned
Error("User not found")
}
Error(query.DatabaseError) -> {
// Query failed (connection error, SQL error, etc.)
Error("Database error")
}
}
// All rows (for "list" queries)
case sql.list_users(db) |> query.all_rows() {
Ok(rows) -> {
// Process all rows
list.map(rows, decode_user)
}
Error(query.DatabaseError) -> {
Error("Database error")
}
}
Error Handling
The QueryError type simplifies error handling:
pub type QueryError {
NotFound // Query succeeded but no rows
DatabaseError // Query failed (connection, SQL, etc.)
}
This is much simpler than Pog’s error types, making it easier to handle common cases.
API Reference
Client Configuration
postgres.new(pool_name)- Create new configpostgres.host(config, host)- Set database hostpostgres.port(config, port)- Set database portpostgres.database(config, name)- Set database namepostgres.user(config, user)- Set database userpostgres.password(config, password)- Set database passwordpostgres.pool_size(config, size)- Set connection pool sizepostgres.connect(config)- Start connection poolpostgres.from_url(url)- Connect from PostgreSQL URL
Query Helpers
query.first_row(result)- Extract first row orNotFoundquery.all_rows(result)- Extract all rows (empty list if none)
Design Principles
This module follows the same quality standards as Dream:
- No nested cases - Clear, flat control flow
- No anonymous functions - Named functions for clarity
- Builder pattern - Consistent, composable APIs
- Type safety -
Resulttypes force error handling - Quality testing - Comprehensive test coverage
About Dream
This module was originally built for the Dream web toolkit, but it’s completely standalone and can be used in any Gleam project. It follows Dream’s design principles and will be maintained as part of the Dream ecosystem.
License
MIT License - see LICENSE file for details.