Skip to content

The Basics

The smallest useful programs you can write against the library.

Everything here uses the synchronous, ref-based API — calls go directly against a Connection, Cursor, or Statement. The Advanced section covers the async actor wrapper.

The call graph at a glance:

Odbc.connect(Dsn(...))    → Connection | ConnectError
  Connection.exec(sql)    → RowCount | NoRowCount | ExecError
  Connection.query(sql)   → Cursor | ExecError
    Cursor.fetch()        → Row | EndOfRows | FetchError
    Cursor.values()       → iterator yielding (Row | FetchError)
  Connection.prepare(sql) → Statement | PrepareError
    Statement.bind(i, v)  → Bound | BindError
    Statement.execute()   → Executed | ExecError           (SELECT)
    Statement.execute_update() → RowCount | ExecError      (DML)
    Statement.fetch()     → Row | EndOfRows | FetchError
  Connection.close()

Every branch is something you handle: errors are values, not exceptions, and the compiler helps you see every case.

  1. Connecting — establishing and closing a Connection
  2. Executing Statementsexec() for DDL and simple DML
  3. Queryingquery(), Cursor, iteration
  4. Reading Rows — typed accessors and SqlNull
  5. SQL Types — the full SqlValue union