mdbgo

module
v0.0.12 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 4, 2026 License: MIT

README

mdbgo

A read-only database/sql driver for Microsoft Access databases (.mdb and .accdb) written in Go. No Microsoft software, ODBC drivers, or OLE DB providers required.

mdbgo provides two drivers — a pure Go implementation and a CGo-based implementation backed by mdbtools.

Driver Name Backend C compiler Speed Memory
Pure Go "gomdb" driver/gomdb No Fastest ~25 KB/op
CGo "cmdb" driver/cmdb zig cc Fast ~2 KB/op

Both drivers are feature-equivalent and produce identical results — verified across 32,549 rows over 5 databases with 0 value differences.

Large scans use a parallel fast path: unencrypted databases are read once into memory (with a bounded cross-connection file cache), page views are zero-copy, and row cracking, WHERE evaluation, and value formatting run across a small worker pool with ordered, backpressure-bounded batches. On the 27k-row lm.mdb workload the pure-Go driver scans all 44 columns of MibTree in ~30 ms (vs ~135 ms for the synchronous path), and a 2-column projection in ~10 ms.

The decode kernels (compressed-ASCII validation, UTF-16 ASCII packing, and compressed-byte expansion) can additionally be built with Go 1.26's experimental simd/archsimd package: build with GOEXPERIMENT=simd and an AVX2-capable CPU to run them as vectorized kernels (roughly 2.5-8x faster than the scalar loops; the exact figures depend on the workload). Without the experiment flag, or on older CPUs, the scalar kernels are used automatically. Note that the end-to-end scan time is dominated by value allocation and interface boxing, so the SIMD gain is visible in the decode step rather than in the full database/sql scan.

Note: Both drivers are read-only — querying existing Access databases only, no writes.

Features

  • Standard database/sql interface
  • Full sqlx compatibility (StructScan, Select, Get, Named queries)
  • Reads MDB (Jet 3/4) and ACCDB files
  • No dependency on Microsoft Access, ACE/Jet OLE DB, or ODBC
  • SQL queries: SELECT (with TOP N [PERCENT]), WHERE (including IN and LIKE/ILIKE), ORDER BY (column or Len(column), ASC/DESC), LIMIT, LIST TABLES, DESCRIBE TABLE
  • Parameterized queries with ? placeholders
  • All 15 Access column types with sql.Null* support
  • Full column metadata (ColumnTypeDatabaseTypeName, ColumnTypeLength, ColumnTypeScanType)
  • Unicode support (CJK, Arabic, etc.)
  • Binary data and OLE object reading
  • DateTime handling with time.Time
  • LIKE pattern matching with Chinese/Unicode text

Installation

go get github.com/Felamande/mdbgo
Pure Go driver — "gomdb"

No C toolchain needed:

CGO_ENABLED=0 go build
CGo driver — "cmdb"

Requires a C compiler. zig cc recommended:

CC="zig cc" CGO_ENABLED=1 go build

No external C libraries needed — mdbtools is compiled in-tree.

Usage

import (
    "database/sql"
    _ "github.com/Felamande/mdbgo/driver/gomdb"  // pure Go
    // _ "github.com/Felamande/mdbgo/driver/cmdb" // or CGo
)

db, _ := sql.Open("gomdb", "path/to/database.mdb") // or "cmdb"

// Query with parameters
rows, _ := db.Query("SELECT ID, Name, Birthday FROM Users WHERE Age > ?", 18)

// sqlx struct scanning
type User struct {
    ID       int64     `db:"ID"`
    Name     string    `db:"Name"`
    Birthday time.Time `db:"Birthday"`
}
var users []User
sqlxDB.Select(&users, "SELECT * FROM Users")

WHERE ... IN and ORDER BY are pure-Go (gomdb) features; the CGo cmdb driver's SQL grammar does not support them. Dotted values such as OIDs must be quoted in IN lists:

rows, _ := db.Query(
    "SELECT TOP 1 * FROM MibTree WHERE OID IN ('1.2.1.1.1.1','1.2.1.1.1','1.2.1.1','1.2.1') ORDER BY Len(OID) DESC",
)
Listing tables
rows, _ := db.Query("LIST TABLES")
Describing a table
rows, _ := db.Query("DESCRIBE TABLE MyTable")

Type Mapping

Access Type Go Type DatabaseTypeName()
Boolean bool "Boolean"
Byte int64 "Byte"
Integer int64 "Integer"
Long Integer int64 "Long Integer"
Currency float64 "Currency"
Single float64 "Single"
Double float64 "Double"
DateTime time.Time "DateTime"
Text string "Text"
Memo string "Memo/Hyperlink"
Binary []byte "Binary"
OLE Object []byte "OLE"
Replication ID string "Replication ID"
Numeric string "Numeric"
Complex int64

Limitations

  • Read-only — no INSERT, UPDATE, DELETE, or DDL operations
  • No transactionsBegin() not supported
  • Client-side parameter interpolation? placeholders are escaped and interpolated into the SQL string
  • BIT/Boolean NULL — Access BIT fields cannot store NULL; NULL coerces to FALSE
  • TEXT length — Unicode TEXT(n) columns report byte length (2×n)
  • No IN (...) syntax — use multiple OR conditions instead
  • Jet SQL only — advanced ACCDB SQL features may not be supported

Architecture

┌──────────────────────────────────────────────┐
│  Go application / sqlx                       │
├──────────────────────────────────────────────┤
│  driver/gomdb/gomdb.go    driver/cmdb/cmdb.go
│  (pure Go, zero CGo)        (CGo + mdbtools) │
├──────────────────────────────────────────────┤
│  internal/gomdb/           internal/cmdb/   │
│  19 .go files               C source + cgo   │
└──────────────────────────────────────────────┘

Both backends parse Access database files directly — the pure Go driver is a ground-up port of mdbtools with no C dependencies, while the CGo driver wraps the original C library.

Project layout

mdbgo/
├── driver/
│   ├── cmdb/                 # CGo driver — registers "cmdb"
│   │   └── cmdb.go
│   └── gomdb/               # Pure Go driver — registers "gomdb"
│       └── gomdb.go
├── internal/
│   ├── cmdb/                 # CGo backend (bridge + mdbtools C source)
│   └── gomdb/               # Pure Go backend (MDB parser, SQL engine)
├── testdata/                 # .mdb test databases
└── temp/                     # Comparison harnesses

Requirements

  • Go 1.26+
  • CGo driver: C compiler (gcc, clang, or zig cc)
  • Pure Go driver: no additional requirements

License

Go code: MIT License

This project embeds mdbtools under the LGPL-2.0-or-later. See internal/cmdb/mdbtools/COPYING.LIB.

Directories

Path Synopsis
driver
cmdb
Package cmdb provides a CGo-based database/sql driver for Microsoft Access (.mdb) files.
Package cmdb provides a CGo-based database/sql driver for Microsoft Access (.mdb) files.
gomdb
Package gomdb provides a pure Go database/sql driver for Microsoft Access (.mdb) files.
Package gomdb provides a pure Go database/sql driver for Microsoft Access (.mdb) files.
odbc
Package odbcbench holds benchmark-only tests that run the large lm.mdb workload through the 32-bit Microsoft Access ODBC driver.
Package odbcbench holds benchmark-only tests that run the large lm.mdb workload through the 32-bit Microsoft Access ODBC driver.
internal
gomdb
Package gomdb is a pure Go implementation of an MDB (Microsoft Access) file reader.
Package gomdb is a pure Go implementation of an MDB (Microsoft Access) file reader.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL