{"id":13496662,"url":"https://github.com/tokio-rs/rdbc","last_synced_at":"2025-04-05T09:07:49.563Z","repository":{"id":41521743,"uuid":"228240704","full_name":"tokio-rs/rdbc","owner":"tokio-rs","description":"Rust DataBase Connectivity (RDBC) :: Common Rust API for database drivers","archived":false,"fork":false,"pushed_at":"2021-05-23T02:42:42.000Z","size":131,"stargazers_count":556,"open_issues_count":23,"forks_count":27,"subscribers_count":38,"default_branch":"master","last_synced_at":"2024-04-14T09:03:41.356Z","etag":null,"topics":["database","driver","mysql","odbc","postgres","rust","sqlite"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tokio-rs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-12-15T19:38:50.000Z","updated_at":"2024-04-05T19:05:48.000Z","dependencies_parsed_at":"2022-09-21T11:52:07.834Z","dependency_job_id":null,"html_url":"https://github.com/tokio-rs/rdbc","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tokio-rs%2Frdbc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tokio-rs%2Frdbc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tokio-rs%2Frdbc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tokio-rs%2Frdbc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tokio-rs","download_url":"https://codeload.github.com/tokio-rs/rdbc/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247312078,"owners_count":20918344,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["database","driver","mysql","odbc","postgres","rust","sqlite"],"created_at":"2024-07-31T19:01:55.661Z","updated_at":"2025-04-05T09:07:49.270Z","avatar_url":"https://github.com/tokio-rs.png","language":"Rust","funding_links":[],"categories":["Rust"],"sub_categories":[],"readme":"\n# Rust DataBase Connectivity (RDBC)\n\n[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)\n[![Docs](https://docs.rs/rdbc/badge.svg)](https://docs.rs/rdbc)\n[![Version](https://img.shields.io/crates/v/rdbc.svg)](https://crates.io/crates/rdbc)\n\nLove them or hate them, the [ODBC](https://en.wikipedia.org/wiki/Open_Database_Connectivity) and [JDBC](https://en.wikipedia.org/wiki/Java_Database_Connectivity) 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.\n\nThis 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.\n\nNote 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.\n\n# Why do we need this when we have Diesel?\n\nThis is filling a different need. I love the [Diesel](https://diesel.rs/) 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.\n\n# RDBC API PoC\n\nNote 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.\n\nThere is currently no `async` support and that will be addressed soon.\n\nThere are also design flaws with the current design, such as the limitation of only being able to create one prepared statement per connection.\n\nWork is in progress of the next iteration of this project and there will definitely be breaking changes.\n\n\n```rust\n/// Represents database driver that can be shared between threads, and can therefore implement\n/// a connection pool\npub trait Driver: Sync + Send {\n    /// Create a connection to the database. Note that connections are intended to be used\n    /// in a single thread since most database connections are not thread-safe\n    fn connect(\u0026self, url: \u0026str) -\u003e Result\u003cBox\u003cdyn Connection\u003e\u003e;\n}\n\n/// Represents a connection to a database\npub trait Connection {\n    /// Create a statement for execution\n    fn create(\u0026mut self, sql: \u0026str) -\u003e Result\u003cBox\u003cdyn Statement + '_\u003e\u003e;\n\n    /// Create a prepared statement for execution\n    fn prepare(\u0026mut self, sql: \u0026str) -\u003e Result\u003cBox\u003cdyn Statement + '_\u003e\u003e;\n}\n\n/// Represents an executable statement\npub trait Statement {\n    /// Execute a query that is expected to return a result set, such as a `SELECT` statement\n    fn execute_query(\u0026mut self, params: \u0026[Value]) -\u003e Result\u003cBox\u003cdyn ResultSet + '_\u003e\u003e;\n\n    /// Execute a query that is expected to update some rows.\n    fn execute_update(\u0026mut self, params: \u0026[Value]) -\u003e Result\u003cu64\u003e;\n}\n\n/// Result set from executing a query against a statement\npub trait ResultSet {\n    /// get meta data about this result set\n    fn meta_data(\u0026self) -\u003e Result\u003cBox\u003cdyn ResultSetMetaData\u003e\u003e;\n\n    /// Move the cursor to the next available row if one exists and return true if it does\n    fn next(\u0026mut self) -\u003e bool;\n\n    fn get_i8(\u0026self, i: u64) -\u003e Result\u003cOption\u003ci8\u003e\u003e;\n    fn get_i16(\u0026self, i: u64) -\u003e Result\u003cOption\u003ci16\u003e\u003e;\n    fn get_i32(\u0026self, i: u64) -\u003e Result\u003cOption\u003ci32\u003e\u003e;\n    fn get_i64(\u0026self, i: u64) -\u003e Result\u003cOption\u003ci64\u003e\u003e;\n    fn get_f32(\u0026self, i: u64) -\u003e Result\u003cOption\u003cf32\u003e\u003e;\n    fn get_f64(\u0026self, i: u64) -\u003e Result\u003cOption\u003cf64\u003e\u003e;\n    fn get_string(\u0026self, i: u64) -\u003e Result\u003cOption\u003cString\u003e\u003e;\n    fn get_bytes(\u0026self, i: u64) -\u003e Result\u003cOption\u003cVec\u003cu8\u003e\u003e\u003e;\n\n    // NOTE that only a subset of data types are supported so far in this PoC\n    // and accessors need to be added for other types such as date and time\n}\n\n/// Meta data for result set\npub trait ResultSetMetaData {\n    fn num_columns(\u0026self) -\u003e u64;\n    fn column_name(\u0026self, i: usize) -\u003e String;\n    fn column_type(\u0026self, i: usize) -\u003e DataType;\n}\n```\n\n# Examples\n\n## Execute a Query\n\n```rust\nlet driver: Arc\u003cdyn rdbc::Driver\u003e = Arc::new(PostgresDriver::new());\nlet mut conn = driver.connect(\"postgres://user:password@127.0.0.1:5433\")?;\nlet mut stmt = conn.prepare(\"SELECT a FROM test\")?;\nlet mut rs = stmt.execute_query(\u0026vec![])?;\nwhile rs.next() {\n  println!(\"{:?}\", rs.get_string(1)?);\n}\n```\n\n# Current Status\n\nThis 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](https://github.com/andygrove/rdbc/issues).\n\nThe immediate priorities though are:\n\n- [x] Announce project and get initial feedback\n- [x] Support parameterized queries\n- [x] Support prepared statements\n- [x] Implement simple SQL console CLI\n- [ ] Design for async\n- [ ] Support connection pooling\n- [ ] Implement comprehensive unit and integration tests\n- [ ] Add support for more data types\n- [ ] Implement RDBC-ODBC bridge\n- [ ] Implement dynamic loading of drivers at runtime\n\n# License\n\nRDBC is licensed under [Apache Licence, Version 2.0](/LICENSE).\n\n# Contributing\n\nPlease refer to the [contributors guide](CONTRIBUTING.md) before contributing to this project and for information on building and testing locally.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftokio-rs%2Frdbc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftokio-rs%2Frdbc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftokio-rs%2Frdbc/lists"}