This is an Oracle database driver for Rust based on ODPI-C

Related tags

Database rust oracle
Overview

Rust-oracle

Build Status Crates.io Docs Docs (in development)

This is an Oracle database driver for Rust based on ODPI-C.

Change Log

See ChangeLog.md.

Build-time Requirements

Run-time Requirements

Usage

Put this in your Cargo.toml:

[dependencies]
oracle = "0.5"

When you need to fetch or bind chrono data types, enable chrono feature:

[dependencies]
oracle = { version = "0.5", features = ["chrono"] }

Examples

Executes select statements and get rows:

` to get a nullable column. // Otherwise, `Err(Error::NullValue)` is returned // for null values. let comm: Option = row.get(2)?; println!(" {:14}| {:>10} | {:>10} |", ename, sal, comm.map_or("".to_string(), |v| v.to_string())); } // Another way to fetch rows. // The rows iterator returns Result<(String, i32, Option )>. println!("---------------|---------------|---------------|"); let rows = conn.query_as::<(String, i32, Option )>(sql, &[&10])?; for row_result in rows { let (ename, sal, comm) = row_result?; println!(" {:14}| {:>10} | {:>10} |", ename, sal, comm.map_or("".to_string(), |v| v.to_string())); }">
use oracle::{Connection, Error};

// Connect to a database.
let conn = Connection::connect("scott", "tiger", "//localhost/XE")?;

let sql = "select ename, sal, comm from emp where deptno = :1";

// Select a table with a bind variable.
println!("---------------|---------------|---------------|");
let rows = conn.query(sql, &[&30])?;
for row_result in rows {
    let row = row_result?;
    // get a column value by position (0-based)
    let ename: String = row.get(0)?;
    // get a column by name (case-insensitive)
    let sal: i32 = row.get("sal")?;
    // Use `Option<...>` to get a nullable column.
    // Otherwise, `Err(Error::NullValue)` is returned
    // for null values.
    let comm: Option<i32> = row.get(2)?;

    println!(" {:14}| {:>10}    | {:>10}    |",
             ename,
             sal,
             comm.map_or("".to_string(), |v| v.to_string()));
}

// Another way to fetch rows.
// The rows iterator returns Result<(String, i32, Option
      
       )>.
      
println!("---------------|---------------|---------------|");
let rows = conn.query_as::<(String, i32, Option<i32>)>(sql, &[&10])?;
for row_result in rows {
    let (ename, sal, comm) = row_result?;
    println!(" {:14}| {:>10}    | {:>10}    |",
             ename,
             sal,
             comm.map_or("".to_string(), |v| v.to_string()));
}

Executes select statements and get the first rows:

= row.get("comm")?; println!("---------------|---------------|---------------|"); println!(" {:14}| {:>10} | {:>10} |", ename, sal, comm.map_or("".to_string(), |v| v.to_string())); // When no rows are found, conn.query_row() returns `Err(Error::NoDataFound)`. // Get the first row as a tupple let row = conn.query_row_as::<(String, i32, Option )>(sql, &[&7566])?; println!("---------------|---------------|---------------|"); println!(" {:14}| {:>10} | {:>10} |", row.0, row.1, row.2.map_or("".to_string(), |v| v.to_string()));">
use oracle::Connection;

// Connect to a database.
let conn = Connection::connect("scott", "tiger", "//localhost/XE")?;

let sql = "select ename, sal, comm from emp where empno = :1";

// Print the first row.
let row = conn.query_row(sql, &[&7369])?;
let ename: String = row.get("empno")?;
let sal: i32 = row.get("sal")?;
let comm: Option<i32> = row.get("comm")?;
println!("---------------|---------------|---------------|");
println!(" {:14}| {:>10}    | {:>10}    |",
         ename,
         sal,
         comm.map_or("".to_string(), |v| v.to_string()));
// When no rows are found, conn.query_row() returns `Err(Error::NoDataFound)`.

// Get the first row as a tupple
let row = conn.query_row_as::<(String, i32, Option<i32>)>(sql, &[&7566])?;
println!("---------------|---------------|---------------|");
println!(" {:14}| {:>10}    | {:>10}    |",
         row.0,
         row.1,
         row.2.map_or("".to_string(), |v| v.to_string()));

Executes non-select statements:

use oracle::Connection;

// Connect to a database.
let conn = Connection::connect("scott", "tiger", "//localhost/XE")?;

conn.execute("create table person (id number(38), name varchar2(40))", &[])?;

// Execute a statement with positional parameters.
conn.execute("insert into person values (:1, :2)",
             &[&1, // first parameter
               &"John" // second parameter
              ])?;

// Execute a statement with named parameters.
conn.execute_named("insert into person values (:id, :name)",
                   &[("id", &2), // 'id' parameter
                     ("name", &"Smith"), // 'name' parameter
                    ])?;

// Commit the transaction.
conn.commit()?;

// Delete rows
conn.execute("delete from person", &[])?;

// Rollback the transaction.
conn.rollback()?;

Prints column information:

use oracle::Connection;

// Connect to a database.
let conn = Connection::connect("scott", "tiger", "//localhost/XE")?;

let sql = "select ename, sal, comm from emp where 1 = 2";
let rows = conn.query(sql, &[])?;

// Print column names
for info in rows.column_info() {
    print!(" {:14}|", info.name());
}
println!("");

// Print column types
for info in rows.column_info() {
    print!(" {:14}|", info.oracle_type().to_string());
}
println!("");

Prepared statement:

use oracle::Connection;

let conn = Connection::connect("scott", "tiger", "//localhost/XE")?;

// Create a prepared statement
let mut stmt = conn.prepare("insert into person values (:1, :2)", &[])?;
// Insert one row
stmt.execute(&[&1, &"John"])?;
// Insert another row
stmt.execute(&[&2, &"Smith"])?;

This is more efficient than two conn.execute(). An SQL statement is executed in the DBMS as follows:

  • step 1. Parse the SQL statement and create an execution plan.
  • step 2. Execute the plan with bind parameters.

When a prepared statement is used, step 1 is called only once.

NLS_LANG parameter

NLS_LANG consists of three components: language, territory and charset. However the charset component is ignored and UTF-8(AL32UTF8) is used as charset because rust characters are UTF-8.

The territory component specifies numeric format, date format and so on. However it affects only conversion in Oracle. See the following example:

("select to_char(10.1) from dual", &[])?; assert_eq!(result, "10,1"); // The decimal mark depends on the territory. // 10.1 is fetched as a number and converted to a string in rust-oracle let result = conn.query_row_as:: ("select 10.1 from dual", &[])?; assert_eq!(result, "10.1"); // The decimal mark is always period(.).">
use oracle::Connection;

// The territory is France.
std::env::set_var("NLS_LANG", "french_france.AL32UTF8");
let conn = Connection::connect("scott", "tiger", "")?;

// 10.1 is converted to a string in Oracle and fetched as a string.
let result = conn.query_row_as::<String>("select to_char(10.1) from dual", &[])?;
assert_eq!(result, "10,1"); // The decimal mark depends on the territory.

// 10.1 is fetched as a number and converted to a string in rust-oracle
let result = conn.query_row_as::<String>("select 10.1 from dual", &[])?;
assert_eq!(result, "10.1"); // The decimal mark is always period(.).

Note that NLS_LANG must be set before first rust-oracle function execution if required.

TODO

License

Rust-oracle and ODPI-C bundled in rust-oracle are under the terms of:

  1. the Universal Permissive License v 1.0 or at your option, any later version; and/or
  2. the Apache License v 2.0.
Comments
  • Request for REF_CURSOR type

    Request for REF_CURSOR type

    I have a program which iterates through millions of rows, some tables having ~50 columns and doing this through the existing functions seems to be quite slow when there are a lot of columns.

    In a similar program written in Java I switched to using REF CURSORs through the JDBC driver and this drastically improved performance. I'd like to be able to use the same in Rust.

    opened by daviessm 9
  • Batching support

    Batching support

    Hello, and thanks a lot for your work.

    I'd like to replace the following JDBC code:

            val updateFlags = conn.prepareStatement("UPDATE table SET field='something' WHERE id = ?")
            ids.toSet().forEach { id ->
                updateFlags.setLong(1, id)
                updateFlags.addBatch()
            }
            updateFlags.executeBatch()
            updateFlags.close()
    

    Which runs decently fast (a few hundred ms for 10k entries)

    I naively tried to run:

        let now = Instant::now();
        let mut stmt = conn.prepare("UPDATE table SET field='something' WHERE id = :1", &[StmtParam::FetchArraySize(10_000)])?;
        for id in &ids {
            stmt.execute(&[id])?;
        }
        println!("Time for {} updates: {}", ids.len(), now.elapsed().as_millis());
        conn.commit()
    

    But unfortunately it takes way too much time as the number of ids increase. (More than 10s for 10k entries).

    I see in README there's "Batch support" mentioned. I guess this covers such feature, am I right?

    If so, well, thank you!

    And could you please notify me by closing this issue whenever you have time to implement it? This way I would know I can go back to dealing with Oracle in Rust!

    Thanks a lot.

    opened by aesteve 7
  • Compilation Error:  `*const i8` cannot be sent between threads safely

    Compilation Error: `*const i8` cannot be sent between threads safely

    I'm getting a compilation failure when pulling in oracle. I've tried using the master branch:

    oracle = { git = "https://github.com/kubo/rust-oracle.git", features = ["chrono"] }
    

    And version 0.3.1:

    oracle = { version = "0.3.1", features = ["chrono"] }
    

    rustc version:

    stable-x86_64-apple-darwin unchanged - rustc 1.39.0 (4560ea788 2019-11-04)
    
    error[E0277]: `*const i8` cannot be sent between threads safely
       --> /Users/nathansculli/.cargo/git/checkouts/rust-oracle-858dd8ce065f6a17/2e61902/src/lib.rs:411:1
        |
    411 | / lazy_static! {
    412 | |     static ref DPI_CONTEXT: ContextResult = {
    413 | |         let mut ctxt = Context {
    414 | |             context: ptr::null_mut(),
    ...   |
    449 | |     };
    450 | | }
        | |_^ `*const i8` cannot be sent between threads safely
        |
        = help: within `ContextResult`, the trait `std::marker::Send` is not implemented for `*const i8`
        = note: required because it appears within the type `binding::dpiErrorInfo`
        = note: required because it appears within the type `ContextResult`
        = note: required because of the requirements on the impl of `std::marker::Sync` for `spin::once::Once<ContextResult>`
        = note: required because it appears within the type `lazy_static::lazy::Lazy<ContextResult>`
        = note: shared static variables must have a type that implements `Sync`
        = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
    
    error: aborting due to previous error
    
    For more information about this error, try `rustc --explain E0277`.
    error: could not compile `oracle`.
    
    opened by scull7 7
  • Usage with asynchronous code problem - how to shut down `.connect()` call that hangs indefinitely

    Usage with asynchronous code problem - how to shut down `.connect()` call that hangs indefinitely

    My problem now is that some of the connections just hang indefinitely. my code:

    #[instrument(skip_all)]
    async fn acquire_connection(
        OracleConnectionCredentials {
            username,
            password,
            connect_string,
        }: OracleConnectionCredentials,
    ) -> Result<Arc<Connection>> {
        tokio::task::spawn_blocking(move || {
            debug!("getting connection out of a pool");
            let conn = oracle::Connector::new(username, password, connect_string)
                .purity(oracle::conn::Purity::New)
                .connect()
                .map(Arc::new);
            conn
        })
        .await
        .wrap_err("thread crashed")
        .and_then(|v| v.wrap_err("acquiring"))
    }
    

    can I either give it some timeout or break this process externally?

    opened by Niedzwiedzw 6
  • Request for setting statement properties ROW_PREFETCH and LOBPREFETCH_SIZE

    Request for setting statement properties ROW_PREFETCH and LOBPREFETCH_SIZE

    I would like to be able to set the properties DEFAULT_LOBPREFETCH_SIZE and DEFAULT_ROW_PREFETCH when connections are created (incl. pooled connections from r2d2_oracle): https://docs.oracle.com/cd/E18283_01/appdev.112/e10646/ociaahan.htm#sthref5292

    opened by daviessm 6
  • `Connection::object_type` cache prevents connection drop

    `Connection::object_type` cache prevents connection drop

    Problem

    Object type cache in connection prevents connection drop, since ObjectTypeInternal inside InnerConn have an Conn (Arc<InnerConn>) to this connection, creating cycle.

    Example

    Example below will always create new connections without dropping previous, leading to memory and socket leaks. This can be checked with $ sudo netstat -tnp | grep <app_name> | grep <port> | grep ESTAB | wc -l. Uncommenting //conn.close().unwrap(); won't help - socket will be closed, but memory will still leak. Also this can be checked with $ DPI_DEBUG_LEVEL=95 cargo run - ODPI logs will show that old connection is not released.

    fn main() {
        let connector = oracle::Connector::new("user", "password", "conn_str");
        loop {
            let conn = connector.connect().unwrap();
            drop(conn.object_type("some_type").unwrap());
            //conn.close().unwrap(); 
            std::thread::sleep(std::time::Duration::from_secs(3));
        }
    }
    

    Possible solution

    I have not found one yet, since there is many Arc's in library, which references same connection from different places, so I doubt this can be easily fixed without many changes. At least it is good idea to document this behavior.

    opened by Flowneee 5
  • ROWID type documentation

    ROWID type documentation

    I need to get the value of ROWIDs selected from a table in the format select rowid from table1 but the Rowid type doesn't seem to be castable to any type in Rust - please could you document in the FromSql trait how I can reference it as a string (as would be returned by ROWIDTOCHAR)?

    opened by daviessm 4
  • OciError ORA-06502: PL/SQL: numeric or value error when try to read Object returned from procedure

    OciError ORA-06502: PL/SQL: numeric or value error when try to read Object returned from procedure

    Hi,

    We try to use rust-oracle for call function that returns an object and get Oracle Error.

    This is the example of errors encountered in Rust Oracle Crate

    ORA-06502: PL/SQL: numeric or value error While trying to execute a query INTO object. If return data contains extra long fields (with unspecified length boundary of 200-300-500 UTF chars) error is produced by connection driver. In case the same query is executed via other DB client(like DBeaver) result is displayed in full with no errors raised. Notes:

    The response overall length somehow affects this behaviour. If Only one field (Attribute A) has extra long data, but still matches the unspecified maximum length boundary, it appears to return correctly. If there are other fields in response (Attributes B C D), summarised length of all fields is compared against unspecified char length limit.

    Steps to reproduce

    1.Create database objects

    CREATE OR REPLACE TYPE T_OBJ_LONG AS OBJECT (
          data1 VARCHAR2(500 CHAR),
          data2 VARCHAR2(500 CHAR),
          data3 VARCHAR2(500 CHAR),
          data4 VARCHAR2(500 CHAR)
    ) ;
    
    CREATE OR REPLACE FUNCTION t_test_long(v_count IN NUMBER) RETURN T_OBJ_LONG
    IS 
     v_res T_OBJ_LONG;
    BEGIN
     v_res := T_OBJ_LONG(
         dbms_random.string('U',v_count),
         dbms_random.string('U',v_count),
         dbms_random.string('U',v_count),
        dbms_random.string('U',v_count)
     ); 
     RETURN v_res;
    END;
    
    1. Try to fetch object with rust-oracle
    use oracle::{ Connection, sql_type, Error };
    use oracle::sql_type::{ObjectType, Object};
    
    fn main() {
    
        static SQL_TEST:&str = "CALL t_test_long(:v_count) INTO :v_result ";
    
        let conn: Connection = Connection::connect("[USER]", "[PASS]", "//[SERVER]:[PORT]/[SERVICE NAME]").unwrap();
    
        let mut result_type = conn.object_type("T_OBJ_LONG").unwrap();
        let mut stmt = conn.prepare(SQL_TEST, &[]).unwrap();
    
        //Everythig works fine when we return 4 string with 10 chars each
    
        stmt.execute(&[
            &10,
            &sql_type::OracleType::Object(result_type)]
        ).unwrap();
    
        let v_result: sql_type::Object = stmt.bind_value("v_result").unwrap();
    
        println!("{:?} + {:?} + {:?} + {:?}",
                 v_result.get::<String>("DATA1").unwrap().len(),
                 v_result.get::<String>("DATA2").unwrap().len(),
                 v_result.get::<String>("DATA3").unwrap().len(),
                 v_result.get::<String>("DATA4").unwrap().len(),
        );
    
        // Reproduce ORA-06502: PL/SQL: numeric or value error
        // Executing a query with extra long data return (500 chars)
    
        result_type = conn.object_type("T_OBJ_LONG").unwrap();
    
        stmt.execute(&[
            &500,
            &sql_type::OracleType::Object(result_type)]
        ).unwrap();
    
        let v_result: sql_type::Object = stmt.bind_value("v_result").unwrap();
    
        println!("{:?} + {:?} + {:?} + {:?}",
                 v_result.get::<String>("DATA1").unwrap().len(),
                 v_result.get::<String>("DATA2").unwrap().len(),
                 v_result.get::<String>("DATA3").unwrap().len(),
                 v_result.get::<String>("DATA4").unwrap().len(),
        );
    
    }
    
    1. Output
    Running `target/debug/rust_oracle_issue`
    10 + 10 + 10 + 10
    thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: OciError(DbError { code: 6502, offset: 0, message: "ORA-06502: PL/SQL: numeric or value error", fn_name: "dpiStmt_execute", action: "execute" })', src/libcore/result.rs:1084:5
    stack backtrace:
       0: backtrace::backtrace::libunwind::trace
                 at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.34/src/backtrace/libunwind.rs:88
       1: backtrace::backtrace::trace_unsynchronized
                 at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.34/src/backtrace/mod.rs:66
       2: std::sys_common::backtrace::_print
                 at src/libstd/sys_common/backtrace.rs:47
       3: std::sys_common::backtrace::print
                 at src/libstd/sys_common/backtrace.rs:36
       4: std::panicking::default_hook::{{closure}}
                 at src/libstd/panicking.rs:200
       5: std::panicking::default_hook
                 at src/libstd/panicking.rs:214
       6: std::panicking::rust_panic_with_hook
                 at src/libstd/panicking.rs:477
       7: std::panicking::continue_panic_fmt
                 at src/libstd/panicking.rs:384
       8: rust_begin_unwind
                 at src/libstd/panicking.rs:311
       9: core::panicking::panic_fmt
                 at src/libcore/panicking.rs:85
      10: core::result::unwrap_failed
                 at src/libcore/result.rs:1084
      11: core::result::Result<T,E>::unwrap
                 at /rustc/625451e376bb2e5283fc4741caa0a3e8a2ca4d54/src/libcore/result.rs:852
      12: rust_oracle_issue::main
                 at src/main.rs:34
      13: std::rt::lang_start::{{closure}}
                 at /rustc/625451e376bb2e5283fc4741caa0a3e8a2ca4d54/src/libstd/rt.rs:64
      14: std::rt::lang_start_internal::{{closure}}
                 at src/libstd/rt.rs:49
      15: std::panicking::try::do_call
                 at src/libstd/panicking.rs:296
      16: __rust_maybe_catch_panic
                 at src/libpanic_unwind/lib.rs:80
      17: std::panicking::try
                 at src/libstd/panicking.rs:275
      18: std::panic::catch_unwind
                 at src/libstd/panic.rs:394
      19: std::rt::lang_start_internal
                 at src/libstd/rt.rs:48
      20: std::rt::lang_start
                 at /rustc/625451e376bb2e5283fc4741caa0a3e8a2ca4d54/src/libstd/rt.rs:64
      21: main
      22: __libc_start_main
      23: _start
    note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
    

    OS : Linux Oracle : Oracle Database 12c Standard Edition Release 12.2.0.1.0 - 64bit Production Client : oracle-instantclient19.3-basic-19.3.0.0.0-1.x86_64

    opened by AndrewKhitrin 4
  • please review r2d2-oracle library

    please review r2d2-oracle library

    Hi

    i have just published v0.1.0 of the r2d2-oracle library: https://github.com/rursprung/r2d2-oracle could you please have a look at it and check if it looks good to you?

    Thanks!

    opened by rursprung 4
  • Re-add Iterator for `ResultSet<T>` and remove that for `&ResultSet<T>`

    Re-add Iterator for `ResultSet` and remove that for `&ResultSet`

    There is already an implicit impl for &mut ResultSet<T> through a blanket impl for iterators in std, so that can be used if the ResultSet should not be consumed. Also, using an immutable borrow for this seemed wrong to me since you obviously couldn't really iterate over the ResultSet from multiple threads.

    opened by rkarp 4
  • get raw blob data?

    get raw blob data?

    I have multiple f32 stored together as blob. it there a way to read the raw blob. or even better to read the f32 to a vec.

    I figure out sqlValue.get<f32>() should get a single one, but I have multiple of them. Thanks.

    opened by swuecho 4
  • Problems with loading large clob values via returning clauses

    Problems with loading large clob values via returning clauses

    I've tried the following code:

    use oracle::*; // oracle = "0.5.6"
    
    const CREATE_TEST_TABLE: &str = "CREATE TABLE test_table (\
            text clob
        )";
    
    fn repro(conn: Connection) {
        let _ = conn.execute("DROP TABLE test_table", &[]);
        conn.execute(CREATE_TEST_TABLE, &[]).unwrap();
        let mut stmt = conn
            .statement("INSERT INTO test_table(text) VALUES (:in1) RETURNING text INTO :out1")
            .build()
            .unwrap();
        let long_text = std::iter::repeat('a').take(4000).collect::<String>();
        stmt.execute_named(&[("in1", &long_text), ("out1", &None::<String>)])
            .unwrap();
        let s: &String = &stmt.returned_values("out1").unwrap()[0];
        assert_eq!(s, &long_text);
    }
    

    I expect that this code passes without an error for a valid connection. Instead of that I get the following error message:

    thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: OciError(DbError { code: 22835, offset: 53, message: "ORA-22835: Buffer too small for CLOB to CHAR or BLOB to RAW conversion (actual: 4000, maximum: 2000)", fn_name: "dpiStmt_execute", action: "execute" })', src/main.rs:16:10
    

    (where line main.rs:16 refers to the unwrap after the execute_named)

    opened by weiznich 2
  • Any reason SqlValues are .dup_by_handle()'d on retrieving a row?

    Any reason SqlValues are .dup_by_handle()'d on retrieving a row?

    Hi,

    as the title says. During profiling of retrieving large sets of data from Oracle databases, I noticed that <Row as RowValue>::get() prominently stands out if there are lots of small rows.

    For each row, the value handles are duplicated - is there any specific reason for this? If there is, than the following is probably wrong and I'd have to accept the sizeable performance hit. I created a small patch which shares the values across row, which worked fine so far.

    Thanks, Christoph

    opened by christoph-heiss 3
  • add build matrix to CI with optional features

    add build matrix to CI with optional features

    it seems that currently optional features (chrono & aq_unstable at this time) are not being tested by the CI workflow. i'd suggest adding a build matrix which covers also these features.

    see e.g. what i did in https://github.com/rursprung/r2d2-oracle/pull/15 for using a build matrix with features. with #58 i'm adding a build matrix to this repo here anyway, so maybe you could then directly extend that and just add the features to the matrix as well (so that they're also tested with both versions of rust and on all OS). you might want to test all four combinations (no features, all features and each feature individually) or just two of them: all features and no features.

    opened by rursprung 0
  • Error with oracle round function

    Error with oracle round function

    When I try to run select round(v, 2) from test_round;, I want to get Float number result, but the return type is Number(0,0).

    Number(0,0) will be parsed as Integer because the scale is 0.

    test_round v 1.111 2.222 3.333

    opened by Wukkkinz-0725 1
  • Working with Oracle Advance Queues

    Working with Oracle Advance Queues

    I am looking to hook up the my rust app to oracle database and we use AQ for communication. I can see in the bindings that there are functions for enq/deq and also for subscriptions, but can not find any examples on how to use them or any rust struct in form of a Queue.

    Is this not (yet) supported or am I missing something?

    opened by sposnjak-cpot 4
  • Request for implementing Sync/Send trait for Row and ResultSet

    Request for implementing Sync/Send trait for Row and ResultSet

    So we can access the rows of the result set of call like conn.query_named in an async function. Then call this async function with tokio spawn. Thanks.

    opened by zhaopinglu 2
Owner
Kubo Takehiro
久保健洋
Kubo Takehiro
This is a maintained rust project that exposes the cpp driver at cpp-driver in a somewhat-sane crate.

cassandra-rs This is a maintained rust project that exposes the cpp driver at https://github.com/datastax/cpp-driver/ in a somewhat-sane crate. For th

Tupshin Harper 51 Aug 20, 2020
A Distributed SQL Database - Building the Database in the Public to Learn Database Internals

Table of Contents Overview Usage TODO MVCC in entangleDB SQL Query Execution in entangleDB entangleDB Raft Consensus Engine What I am trying to build

Sarthak Dalabehera 38 Jan 2, 2024
Oracle support for the r2d2 connection pool

r2d2-oracle The documentation can be found on docs.rs. Oracle support for the r2d2 connection pool. This fits in between the r2d2 connection manager a

Ralph Ursprung 7 Dec 14, 2022
cogo rust coroutine database driver (Mysql,Postgres,Sqlite)

cdbc Coroutine Database driver Connectivity.based on cogo High concurrency,based on coroutine No Future<'q,Output=*>,No async fn, No .await , no Poll*

co-rs 10 Nov 13, 2022
Asyncronous Rust Mysql driver based on Tokio.

mysql-async Tokio based asynchronous MySql client library for rust programming language. Installation Library hosted on crates.io. [dependencies] mysq

Anatoly I 292 Dec 30, 2022
An unofficial Logitech HID++>2.0 driver based on the original logiops by PixlOne

ruhroh An unofficial Logitech HID++>2.0 driver based on the original logiops by PixlOne Configuration Refer to the docs for details. The default locat

Matthew Wilks 3 Dec 11, 2022
An ArangoDB driver for Rust

Rincon Rincon is an ArangoDB driver for Rust. It enables low level access to ArangoDB in a typesafe and Rust idiomatic manner. The name Rincon is deri

Innoave 35 Mar 21, 2021
The official MongoDB Rust Driver

MongoDB Rust Driver This repository contains the officially supported MongoDB Rust driver, a client side library that can be used to interact with Mon

mongodb 1.1k Dec 30, 2022
TDS 7.2+ (mssql / Microsoft SQL Server) async driver for rust

Tiberius A native Microsoft SQL Server (TDS) client for Rust. Supported SQL Server versions Version Support level Notes 2019 Tested on CI 2017 Tested

Prisma 189 Dec 25, 2022
Native PostgreSQL driver for the Rust programming language

Rust-Postgres PostgreSQL support for Rust. postgres Documentation A native, synchronous PostgreSQL client. tokio-postgres Documentation A native, asyn

Steven Fackler 2.8k Jan 8, 2023
Official Skytable client driver for Rust

Skytable client Introduction This library is the official client for the free and open-source NoSQL database Skytable. First, go ahead and install Sky

Skytable 29 Nov 24, 2022
This is superseded by the official MongoDB Rust Driver

This Repository is NOT a supported MongoDB product MongoDB Rust Driver Prototype NOTE: This driver is superseded by the official MongoDB Rust driver,

MongoDB, Inc. Labs 382 Nov 15, 2022
Easy to use rust driver for arangoDB

arangors arangors is an intuitive rust client for ArangoDB, inspired by pyArango. arangors enables you to connect with ArangoDB server, access to data

fMeow 116 Jan 1, 2023
A Rust port of Pimoroni's uc8151 driver

uc8151-rs - a no-std Rust library for the UC8151(IL0373) e-ink display This is a Rust port of the Pimoroni UC8151 library. UC8151 is also sometimes re

null 6 Dec 15, 2022
ENC28J60 Linux network driver written in Rust.

enc28j60rs ENC28J60 Linux ethernet driver written in Rust. Tested with Raspberry Pi 4 Model B + Linux kernel 6.2.8 + Raspberry Pi OS AArch64. Kernel T

Ryo Munakata 11 May 1, 2023
MIPI Display Serial Interface unified driver

mipidsi This crate provides a generic display driver to connect to TFT displays that implement the MIPI DSI. Uses display_interface to talk to the har

Aleš Katona 31 Dec 20, 2022
TTVM Intermediate Representation driver

ttir - TTVM IR Driver ttir is driver for the TTVM IR located in ttvm. Usage Run the following command in your shell: cargo install ttir Features Easy

maDeveloper 1 Nov 2, 2021
e-paper/e-ink monitor linux driver

Ardoise: e-paper/e-ink monitor Goal: Create a e-paper/e-ink monitorfor linux. My personal use is a typewriter. Written in Rust Latency is 0,2s when th

Cyril Jacquet 1 Dec 8, 2022
PackDb is a simple messagepack based database in rust

PackDb is a simple key value messagepack store Inspired by kwik It uses your local storage

Tricked 2 Apr 1, 2022