#odbc #database #sql

odbc-api

Write ODBC Applications in (mostly) safe Rust

30 releases (16 breaking)

new 0.17.0 Feb 28, 2021
0.15.0 Feb 12, 2021
0.12.0 Dec 7, 2020
0.10.3 Nov 21, 2020

#213 in Database interfaces

Download history 49/week @ 2020-11-12 85/week @ 2020-11-19 61/week @ 2020-11-26 98/week @ 2020-12-03 53/week @ 2020-12-10 6/week @ 2020-12-17 6/week @ 2020-12-24 23/week @ 2020-12-31 28/week @ 2021-01-07 67/week @ 2021-01-14 34/week @ 2021-01-21 34/week @ 2021-01-28 82/week @ 2021-02-04 226/week @ 2021-02-11 75/week @ 2021-02-18 52/week @ 2021-02-25

255 downloads per month
Used in 2 crates

MIT license

255KB
3.5K SLoC

ODBC-API

ODBC (Open Database Connectivity) bindings for Rust.

Docs MIT licensed Published Coverage Status

Usage

To utilize this library you need to link against the odbc library of your systems odbc driver manager. It should be automatically detected by the build. On Windows systems it should always be preinstalled on Linux distributions and OS-X you should verify that a driver manager like unix-odbc is installed.

Check the guide for code examples and a tour of the features.

Features

  • Connect using either Data Source names (DSN) or connection strings
  • Provide nice erros and log diagnostic output.
  • Support for columnwise bulk inserts.
  • Support for columnwise bulk queries.
  • Support for rowise bulk inserts.
  • Support for rowise bulk queries.
  • Support for Output parameters of stored procedures.
  • Support prepared and 'one shot' queries.
  • Transactions
  • Pass parameters to queries
  • Support for async
  • Support for Multithreading

Motivation

Supports writing ODBC Application in Rust. Prior work in this area has been done:

  • odbc-sys: Bare bindings to the ODBC C Library. Declares C-Function signatures and handles linking. All other libraries mentioned are based on this one.
  • odbc-safe: (Mostly) safe wrapper around odbc-sys. Apart from protecting against unsafe behaviour, this library also tries to prevent invalid use of the ODBC API by modelling state transitions.
  • odbc-rs: Higher level and more idiomatic bindings. Wraps odbc-safe.

So why odbc-api? This is a somewhat less ambitious and more opinionated rewrite of odbc-safe. odbc-safe aimed to model all the possible state transitions offered by odbc. This turned out to be both, incredibly challenging to implement and maintain, and cumbersome to use. ODBCs way of sharing mutable buffers is very much at odds with Rusts type system, introducing significant complexity in an unopinionated general purpose wrapper. This library leaves the low level odbc abstractions as unsafe as they are, but aims to provide idiomatic interfaces for the usual high level use cases.

Design decisions

Here are some of the tradeoffs I made in this library to make my life (and hopefully that of the users a bit easier).

Commiting to one version of the ODBC Api

The underlying odbc-sys crate does not limit you to a specific ODBC version. This crate however currently fixes the ODBC version to 3.8.

Use of the Wide ODBC methods returning UTF-16

Idiomatic Rust uses UTF-8. Sadly the narrow C-Methods in ODBC do not always imply the use of UTF-8, which can cause some mess with encodings (think about a Windows system with a Japanese local). Although the use of the wide methods may require the additional encoding, decoding and allocation of strings it works consistently on all platforms and configuration. Also application performance does rarely depend on how fast we process the connection string. Correct handling of the buffers for the payload is far more important. That being said. This library is not a zero cost abstraction. In some setups you may very well be able to assume that you can directly use UTF-8 and this API does introduce some overhead on such systems.

Warnings are logged

ODBC calls produce a Result. If successful they may also produce any number of warnings. Applications currently have no means to react to these warnings. They are logged using the log crate with the warn severity. Rust type systems would have been powerful enough to express the presence of warnings in the Return type, yet I did not want to loose out on simply using ?-operator for error propagation. Also I never wanted to do something with these warnings besides logging them. Some overhead is introduced, as the messages for these warnings are allocated, even if you do not register a backend for the log crate at all.

Dependencies

~0.6–1.1MB
~24K SLoC