• Stars
    star
    558
  • Rank 79,819 (Top 2 %)
  • Language
    Rust
  • License
    Apache License 2.0
  • Created almost 5 years ago
  • Updated over 3 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Rust DataBase Connectivity (RDBC) :: Common Rust API for database drivers

Rust DataBase Connectivity (RDBC)

License Docs Version

Love them or hate them, the ODBC and JDBC standards have made it easy to use a wide range of desktop and server products with many different databases thanks to the availability of database drivers implementing these standards.

This project provides a Rust equivalent API as well as reference implementations (drivers) for Postgres, MySQL, and SQLite. There is also an RDBC-ODBC driver being developed, that will allow ODBC drivers to be called via the RDBC API, so that it is also possible to connect to databases that do not yet have Rust drivers available.

Note that the provided RDBC drivers are just wrappers around existing database driver crates and this project is not attempting to build new drivers from scratch but rather make it possible to leverage existing drivers through a common API.

Why do we need this when we have Diesel?

This is filling a different need. I love the Diesel approach for building applications but if you are building a generic SQL tool, a business intelligence tool, or a distributed query engine, there is a need to connect to different databases and execute arbitrary SQL. This is where we need a standard API and available drivers.

RDBC API PoC

Note that the design of the RDBC API is intentionally modeled directly after ODBC and JDBC (except that indices are 0-based rather than 1-based) and that is likely to change to make this more idiomatic for Rust.

There is currently no async support and that will be addressed soon.

There are also design flaws with the current design, such as the limitation of only being able to create one prepared statement per connection.

Work is in progress of the next iteration of this project and there will definitely be breaking changes.

/// Represents database driver that can be shared between threads, and can therefore implement
/// a connection pool
pub trait Driver: Sync + Send {
    /// Create a connection to the database. Note that connections are intended to be used
    /// in a single thread since most database connections are not thread-safe
    fn connect(&self, url: &str) -> Result<Box<dyn Connection>>;
}

/// Represents a connection to a database
pub trait Connection {
    /// Create a statement for execution
    fn create(&mut self, sql: &str) -> Result<Box<dyn Statement + '_>>;

    /// Create a prepared statement for execution
    fn prepare(&mut self, sql: &str) -> Result<Box<dyn Statement + '_>>;
}

/// Represents an executable statement
pub trait Statement {
    /// Execute a query that is expected to return a result set, such as a `SELECT` statement
    fn execute_query(&mut self, params: &[Value]) -> Result<Box<dyn ResultSet + '_>>;

    /// Execute a query that is expected to update some rows.
    fn execute_update(&mut self, params: &[Value]) -> Result<u64>;
}

/// Result set from executing a query against a statement
pub trait ResultSet {
    /// get meta data about this result set
    fn meta_data(&self) -> Result<Box<dyn ResultSetMetaData>>;

    /// Move the cursor to the next available row if one exists and return true if it does
    fn next(&mut self) -> bool;

    fn get_i8(&self, i: u64) -> Result<Option<i8>>;
    fn get_i16(&self, i: u64) -> Result<Option<i16>>;
    fn get_i32(&self, i: u64) -> Result<Option<i32>>;
    fn get_i64(&self, i: u64) -> Result<Option<i64>>;
    fn get_f32(&self, i: u64) -> Result<Option<f32>>;
    fn get_f64(&self, i: u64) -> Result<Option<f64>>;
    fn get_string(&self, i: u64) -> Result<Option<String>>;
    fn get_bytes(&self, i: u64) -> Result<Option<Vec<u8>>>;

    // NOTE that only a subset of data types are supported so far in this PoC
    // and accessors need to be added for other types such as date and time
}

/// Meta data for result set
pub trait ResultSetMetaData {
    fn num_columns(&self) -> u64;
    fn column_name(&self, i: usize) -> String;
    fn column_type(&self, i: usize) -> DataType;
}

Examples

Execute a Query

let driver: Arc<dyn rdbc::Driver> = Arc::new(PostgresDriver::new());
let mut conn = driver.connect("postgres://user:[email protected]:5433")?;
let mut stmt = conn.prepare("SELECT a FROM test")?;
let mut rs = stmt.execute_query(&vec![])?;
while rs.next() {
  println!("{:?}", rs.get_string(1)?);
}

Current Status

This is just an experimental PoC and is not currently suitable for anything. However, I do intend to make it useful pretty quickly and I am tracking issues here.

The immediate priorities though are:

  • Announce project and get initial feedback
  • Support parameterized queries
  • Support prepared statements
  • Implement simple SQL console CLI
  • Design for async
  • Support connection pooling
  • Implement comprehensive unit and integration tests
  • Add support for more data types
  • Implement RDBC-ODBC bridge
  • Implement dynamic loading of drivers at runtime

License

RDBC is licensed under Apache Licence, Version 2.0.

Contributing

Please refer to the contributors guide before contributing to this project and for information on building and testing locally.

More Repositories

1

tokio

A runtime for writing reliable asynchronous applications with Rust. Provides I/O, networking, scheduling, timers, ...
Rust
23,031
star
2

axum

Ergonomic and modular web framework built with Tokio, Tower, and Hyper
Rust
17,992
star
3

mio

Metal I/O library for Rust.
Rust
6,301
star
4

tracing

Application level tracing for Rust.
Rust
5,365
star
5

mini-redis

Incomplete Redis client and server implementation using Tokio - for learning purposes only
Rust
3,927
star
6

prost

PROST! a Protocol Buffers implementation for the Rust Language
Rust
3,766
star
7

console

a debugger for async rust!
Rust
3,542
star
8

loom

Concurrency permutation testing tool for Rust.
Rust
1,847
star
9

bytes

Utilities for working with bytes
Rust
1,739
star
10

io-uring

The `io_uring` library for Rust
Rust
1,037
star
11

tokio-uring

An io_uring backed runtime for Rust
Rust
946
star
12

turmoil

Add hardship to your tests
Rust
772
star
13

tokio-proto

A network application framework for Rust
Rust
694
star
14

slab

Slab allocator for Rust
Rust
641
star
15

tokio-core

I/O primitives and event loop for async I/O in Rust
Rust
628
star
16

async-stream

Asynchronous streams for Rust using async & await notation
Rust
568
star
17

tokio-minihttp

Protocol implementation experimentations
Rust
425
star
18

tokio-metrics

Utilities for collecting metrics from a Tokio application
Rust
254
star
19

tls

A collection of Tokio based TLS libraries.
Rust
243
star
20

tracing-opentelemetry

Rust
233
star
21

website

Website for the Tokio project
TypeScript
211
star
22

valuable

Rust
185
star
23

async-backtrace

Rust
162
star
24

tokio-io

Core I/O primitives for asynchronous I/O in Rust.
Rust
124
star
25

tokio-socks5

An example SOCKSv5 server implementation with tokio
Rust
100
star
26

tokio-tls

An implementation of TLS/SSL streams for Tokio
Rust
95
star
27

simulation

Framework for simulating distributed applications
Rust
92
star
28

tokio-timer

Timer facilities for Tokio
Rust
83
star
29

tokio-service

The core `Service` trait in Tokio and support
Rust
81
star
30

tokio-line

Line protocol for Tokio
Rust
64
star
31

tokio-redis

Redis client for Tokio
Rust
58
star
32

tokio-uds

Unix Domain Sockets for tokio
Rust
52
star
33

doc-push

Tokio doc blitz effort - A concerted effort to improve Tokio's documentation.
50
star
34

tokio-compat

Streamline updating a Tokio 0.1 application to Tokio 0.2.
Rust
48
star
35

book

45
star
36

tokio-openssl

OpenSSL bindings for Tokio
Rust
37
star
37

tokio-middleware

A collection of Tokio middleware
Rust
28
star
38

tokio-rfcs

22
star
39

async

Utilities building on top of Rust's async primitives.
Rust
22
star
40

console-gsoc

Google Summer of Code tokio-console prototype
Rust
12
star
41

service-fn

A service implemented by a closure
Rust
11
star
42

gsoc

Organize the Google Summer of Code projects.
6
star
43

cargo-tokio

A cargo subcommand to help building the Tokio project.
Rust
4
star
44

website-next

Next iteration of the Tokio website.
TypeScript
1
star