Skip to content

Connecting

Every ODBC program starts by asking a driver manager to open a connection. The Pony entry point is Odbc.connect.

The smallest program

use "lib:odbc"
use "odbc"

actor Main
  new create(env: Env) =>
    let dsn_name =
      try env.args(1)?
      else "psqlred"
      end

    match Odbc.connect(Dsn("DSN=" + dsn_name))
    | let conn: Connection =>
      env.out.print("Connected to " + dsn_name)
      conn.close()
      env.out.print("Closed.")
    | let e: ConnectError =>
      env.err.print("connect: " + e.string())
    end

Three things to notice.

Dsn is a distinct type

Dsn("DSN=psqlred") wraps the connection string in a val class. The point: connection strings often contain credentials, so they can’t be accidentally confused with String values that might get logged or surfaced to users. The library never renders a Dsn in error messages and redacts driver-supplied diagnostics too.

Odbc.connect returns a union

fun connect(dsn: Dsn, validate_utf8: Bool = true): (Connection | ConnectError)

No exception, no partial function, no None — just a union. Match on it.

validate_utf8 = true keeps a safety check on text columns. Setting it to false is faster but only safe if you trust the data source.

Connection.close() is idempotent

Safe to call multiple times. A _final() safety net catches forgotten closes, but explicit is preferred: close() rolls back any in-flight transaction (see Transactions) and releases the SQLHDBC and SQLHENV handles immediately.

Running it

From code-samples/:

corral run -- ponyc -o build 01-connect
./build/01-connect

Output:

Connected to psqlred
Closed.

Pass a different DSN name as argv[1] if yours isn’t psqlred:

./build/01-connect my_dsn

What a failure looks like

./build/01-connect definitely_not_a_real_dsn
connect: ConnectError: driver connect failed [IM002]

That’s the redacted form. The driver’s raw message can contain credentials, so .string() never includes it. For debugging, use e.unsafe_diag() — see Errors and Diagnostics.

What’s next

A connection on its own does nothing. Executing Statements introduces exec().