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().