PGL

test Package Version Hex Docs

pgl is a PostgreSQL client written in Gleam.

Features

Example

import gleam/dynamic/decode
import gleam/list
import pgl
import pg_value

pub fn main() {
  let conf =
    pgl.config
    |> pgl.host("localhost")
    |> pgl.port(5432)
    |> pgl.database("my_db")
    |> pgl.username("postgres")
    |> pgl.password("postgres")

  let db = pgl.new(conf)

  let assert Ok(_) = pgl.start(db)

  let conn = pgl.connection(db)

  let assert Ok(queried) =
    "SELECT id, name FROM users WHERE id = $1"
    |> pgl.sql
    |> pgl.values([pg_value.int(1)])
    |> pgl.query(conn)

  let assert Ok(users) =
    queried.rows
    |> list.try_map(decode.run(_, {
      use id <- decode.field(0, decode.int)
      use name <- decode.field(1, decode.string)
      decode.success(#(id, name))
    }))

  let assert Ok(_) = pgl.shutdown(db)
}

URL Configuration

You can also configure a connection from a URL:

let assert Ok(conf) =
  "postgres://user:pass@localhost:5432/my_db?sslmode=verify-ca"
  |> pgl.from_url

Supported sslmode values: disable, require, verify-ca, verify-full.

Rows as Dicts

By default, rows are returned as tuples. To return rows as Dicts where columns are keyed by name:

let conf =
  pgl.config
  |> pgl.rows_as_dict(True)

Pipelining

Use pgl.batch to send multiple queries without waiting for each to complete, reducing network round trips:

let queries = [
  pgl.Query("INSERT INTO users (name) VALUES ($1)", [pg_value.text("Alice")]),
  pgl.Query("INSERT INTO users (name) VALUES ($1)", [pg_value.text("Bob")]),
]

let assert Ok(results) = pgl.batch(queries, conn)

Transactions and Savepoints

Use pgl.transaction for automatic commit/rollback:

let assert Ok(result) =
  pgl.transaction(conn, fn(tx) {
    let assert Ok(_) =
      "INSERT INTO users (name) VALUES ($1)"
      |> pgl.sql
      |> pgl.values([pg_value.text("Alice")])
      |> pgl.query(tx)

    Ok("done")
  })

If the callback returns Error or raises an exception, the transaction is rolled back. Nested savepoints are also supported:

pgl.transaction(conn, fn(tx) {
  pgl.savepoint(tx, fn(sp) {
    // If this fails, only the savepoint is rolled back
    Ok(Nil)
  })
})

Supported Versions

Installation

gleam add pgl

Further documentation can be found at https://hexdocs.pm/pgl.

Development

Tests require a running PostgreSQL instance:

docker compose up      # Start PostgreSQL
gleam test             # Run the tests

Acknowledgements

Early iterations of this package were based on pgo and its influence remains. pog and postgrex were also helpful in writing this package.

Search Document