Repository navigation
Releases: xo/odbc
Release list
v0.1.1
This release fixes one bug and documents a crash that is not a fault of odbc.
Fixed
A statement that returns no result set, such as CREATE TABLE, sent through QueryContext, failed on the first Next with fetching: return code -1 with no diagnostic. The driver fetched from a statement that has no result. It now returns no rows, and Err and Close report no error. A client that sends every statement through QueryContext, as usql can, met this. TestQueryWithoutResult covers all six tested databases.
Documented
- The README has a FAQ entry for a crash of a program that links both
go-sqlite3and the DuckDB bindings and uses the SQLite ODBC driver. The DuckDB bindings link with-rdynamic, so the program exports thesqlite3_*functions ofgo-sqlite3, and the SQLite ODBC driver binds to them while it also uses the SQLite of the system. The first query then faults. Buildgo-sqlite3with the taglibsqlite3, leave one of the two libraries out, or build withCGO_ENABLED=0.odbccannot prevent it. - The SQLite ODBC driver answers a
VALUESstatement withSQL_NO_DATA, so the driver manager refuses to describe its columns withHY010.select * from (values (1))works. The backlog records it as a known limit.
Everything else in v0.1.0 is unchanged, and CI passed on all three systems for this release.
v0.1.0
This is the first release of odbc, a database/sql driver for ODBC written in pure Go. It loads the ODBC driver manager of the system at run time with purego. It needs no cgo and no C compiler. One code base serves Linux, macOS and Windows.
Install
go get github.com/xo/odbc@v0.1.0You need an ODBC driver manager and the ODBC driver of your database on the machine. The README explains the data source name and has an FAQ.
What it does
- It connects with a URL such as
odbc+PostgreSQL+Unicode://user:pass@host/db, or with an ODBC connection string. - It supports prepared and direct statements, bound parameters, transactions with isolation levels, and cancellation through the context.
- Values have the Go types of the
dbimpkinds. A decimal is a*apd.Decimal, a date is adbimp.Date, and a timestamp with no zone is adbimp.LocalDateTime. - It finds the size of
SQLWCHARwhen it loads the driver manager, so UTF-16 and UTF-32 managers both work. - Statements take the same options as the other
dbimpdrivers:WithTimeout,WithDatabase,WithReadonly,WithParameter,WithMaxRows,WithNoScanandWithFetchSize. An option that a database driver cannot honor fails withdbimp.ErrNotSupported. WithFetchSizereads rows in blocks. It was two to four times faster in the tests, and it never returns a value that was cut short.- A program can ask the driver about the database:
odbc.Drivers,odbc.DataSources,odbc.ConnwithGetInfo*,Tables,ColumnsandPrimaryKeys,Config.OnWarning,Config.TraceFile, and error classes such asodbc.ErrIntegrity.
What is tested
The tests run the dbmeta fixtures and queries and a round trip of each kind of value. CI runs them on every push and every night.
| System | Databases |
|---|---|
| Linux | PostgreSQL, MariaDB, MySQL, SQL Server, SQLite, DuckDB |
| macOS | PostgreSQL, MariaDB, SQLite, DuckDB |
| Windows | PostgreSQL, MySQL, SQLite, DuckDB |
MariaDB Connector/ODBC serves both MariaDB and MySQL. SQL Server is tested on Linux only.
Known limits
WithReadonly(true)always fails withdbimp.ErrNotSupported, because three of the six databases accept the ODBC read only mode and still write.- PostgreSQL
timestamptzloses its zone, becausepsqlODBCreports it as a timestamp with no zone. - Non-ASCII text in an SQL literal is wrong with the SQLite ODBC driver on macOS and in a container with no locale. An argument is fine.
iODBCworks, but the database drivers of Homebrew are built forunixODBCand read its text wrongly.- MariaDB Connector/ODBC before 3.2 lists no primary key of a MySQL 8 table.
The decisions behind all of this are in docs/decisions/, and docs/BACKLOG.md lists the work that is left.