Coder Social home page Coder Social logo

orientdb-rs's Introduction

orientdb-rs

A Rust Client for OrientDB

OrientDB Client

A Rust Client for OrientDB. Supports sync and async (tokio and async-std)

Installation

Install from crates.io

[dependencies]
orientdb-client = "*"

Cargo Features

  • async-std-runtime: use the async APIs with async-std.
  • tokio-runtime: use the async APIs with tokio.
  • uuid: Add support for UUID.
  • sugar: Add ergonimic APIs for querying and binding results to structs

Example

Basic Usage Synchronous

use orientdb_client::{OrientDB};

fn main() -> Result<(), Box<std::error::Error>> {
    let client = OrientDB::connect(("localhost",2424))?;

    let session = client.session("demodb","admin","admin")?;

    let results : Vec<_> = session.query("select from V where id = :param").named(&[("param", &1)]).run()?.collect();


    println!("{:?}", results);

    Ok(())
}

Basic Usage Asynchronous

For async-std

activate the feature async-std-runtime

orientdb-client = { version = "*", features = ["async-std-runtime"] }

use async_std::task::block_on;
use futures::StreamExt;
use orientdb_client::aio::OrientDB;
use orientdb_client::OrientResult;

fn main() -> OrientResult<()> {
    block_on(async {
        let client = OrientDB::connect(("localhost", 2424)).await?;

        let session = client.session("demodb", "admin", "admin").await?;

        let mut stream = session.query("select from V limit 10").run().await?;

        while let Some(item) = stream.next().await {
            println!("Record {:?}", item?);
        }

        Ok(())
    })
}

For tokio

activate the feature tokio-runtime

orientdb-client = { version = "*", features = ["tokio-runtime"] }

use futures::StreamExt;
use orientdb_client::aio::OrientDB;
use orientdb_client::OrientResult;

#[tokio::main]
async fn main() -> OrientResult<()> {
    let client = OrientDB::connect(("localhost", 2424)).await?;

    let session = client.session("demodb", "admin", "admin").await?;

    let mut stream = session.query("select from V limit 10").run().await?;

    while let Some(item) = stream.next().await {
        println!("Record {:?}", item?);
    }

    Ok(())
}

Additional Features

sugar feature

The sugar feature add 3 methods to the query builder for spawning the query.

  • fetch_one
  • fetch
  • stream for async or iter for sync

They should be used instead of run APIs when you want to execute the query and map the OResult into a struct.

The sugar is supported in sync and async mode.

fetch_one

Consume the stream and fetch the first result if any.

use orientdb_client::derive::FromResult;
#[derive(FromResult, Debug)]
struct User {
    name: String,
}

// fetch one
let user: Option<User> = session
    .query("select from OUser limit 1")
    .fetch_one()
    .await?;

println!("User {:?}", user);`

fetch

Collect the stream to a Vec and map to struct.

use orientdb_client::derive::FromResult;
#[derive(FromResult, Debug)]
struct User {
    name: String,
}

// fetch 
let user: Vec<User> = session
    .query("select from OUser limit 1")
    .fetch()
    .await?;

println!("Users {:?}", user);`

stream

Map each item of the stream to a struct.

use orientdb_client::derive::FromResult;
#[derive(FromResult, Debug)]
struct User {
    name: String,
}

// fetch stream and collect
let stream = session
            .query("select from OUser")
            .stream::<User>()
            .await?
            .collect::<Vec<_>>()
            .await;
println!("Users {:?}", user);

Development

Compiling

git clone https://github.com/wolf4ood/orientdb-rs.git
cd orientdb-rs
cargo build

Running Tests

You can use docker-compose to start an instance for testing. Use the env variable ORIENTDB_SERVER in order to specify the version of OrientDB

cd docker-compose
export ORIENTDB_SERVER=3.0.23
docker-compose up -d
cd ..
cargo test

orientdb-rs's People

Contributors

alex179ohm avatar wolf4ood avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

orientdb-rs's Issues

UUID type support

Since ODB doesn't support natively uuid type.
The support will be only at API level and translated into the string representation of UUID

I can't get the Basic Usage Synchronous example to work.

main.rs

use orientdb_client::{OrientDB}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = OrientDB::connect(("localhost",2424))?;

    let session = client.session("demodb","admin","admin")?;

    let results : Vec<_> = session.query("select from V where id = :param").named(&[("param", &1)]).run()?.collect();


    println!("{:?}", results);

    Ok(())
}

terminal

[folaht@pjehrsohmehj src]$ RUST_BACKTRACE=1 cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.15s
     Running `/home/folaht/Nwaȥ/Êspas dû travaj/neovîm/Âp/sn_grufs/target/debug/sn_grufs`
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Pool(Error(Some("")))', /home/folaht/.cargo/registry/src/github.com-1ecc6299db9ec823/orientdb-client-0.5.1/src/sync/network/cluster.rs:42:51
stack backtrace:
   0: rust_begin_unwind
             at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/std/src/panicking.rs:493:5
   1: core::panicking::panic_fmt
             at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/core/src/panicking.rs:92:14
   2: core::option::expect_none_failed
             at /rustc/cb75ad5db02783e8b0222fee363c5f63f7e2cf5b/library/core/src/option.rs:1268:5
   3: core::result::Result<T,E>::unwrap
             at /home/folaht/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/result.rs:973:23
   4: orientdb_client::sync::network::cluster::ClusterBuilder::build::{{closure}}
             at /home/folaht/.cargo/registry/src/github.com-1ecc6299db9ec823/orientdb-client-0.5.1/src/sync/network/cluster.rs:42:26
   5: core::iter::adapters::map::map_fold::{{closure}}
             at /home/folaht/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/iter/adapters/map.rs:80:28
   6: core::iter::traits::iterator::Iterator::fold
             at /home/folaht/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/iter/traits/iterator.rs:2023:21
   7: <core::iter::adapters::map::Map<I,F> as core::iter::traits::iterator::Iterator>::fold
             at /home/folaht/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/iter/adapters/map.rs:120:9
   8: core::iter::traits::iterator::Iterator::for_each
             at /home/folaht/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/iter/traits/iterator.rs:678:9
   9: <alloc::vec::Vec<T,A> as alloc::vec::SpecExtend<T,I>>::spec_extend
             at /home/folaht/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/alloc/src/vec.rs:2568:17
  10: <alloc::vec::Vec<T> as alloc::vec::SpecFromIterNested<T,I>>::from_iter
             at /home/folaht/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/alloc/src/vec.rs:2336:9
  11: <alloc::vec::Vec<T> as alloc::vec::SpecFromIter<T,I>>::from_iter
             at /home/folaht/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/alloc/src/vec.rs:2451:20
  12: <alloc::vec::Vec<T> as core::iter::traits::collect::FromIterator<T>>::from_iter
             at /home/folaht/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/alloc/src/vec.rs:2181:9
  13: core::iter::traits::iterator::Iterator::collect
             at /home/folaht/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/iter/traits/iterator.rs:1670:9
  14: orientdb_client::sync::network::cluster::ClusterBuilder::build
             at /home/folaht/.cargo/registry/src/github.com-1ecc6299db9ec823/orientdb-client-0.5.1/src/sync/network/cluster.rs:37:23
  15: orientdb_client::sync::client::OrientDB::connect
             at /home/folaht/.cargo/registry/src/github.com-1ecc6299db9ec823/orientdb-client-0.5.1/src/sync/client.rs:29:23
  16: sn_grufs::main
             at ./main.rs:18:22
  17: core::ops::function::FnOnce::call_once
             at /home/folaht/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ops/function.rs:227:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

Async Connection refactor

The Connection struct (only async) should run on a separated task which accept request via channels and respond back also with channels.

This decoupling would enable the implementation of live queries with push notifications which can happen on the same socket of normal requests.

Retry API

The Session should expose retry API that retry the logic in case of MVCC exceptions

The API should look like

session.with_retry(10,|tx| {
 tx.command(...)
})

Field not found with `sugar` mapping

The mapping to structs should use optional when specified for optional fields.

Currently this emit an error

    #[derive(orientdb_client::derive::FromResult, Debug, PartialEq)]
        struct Person {
            name: String,
            age : Option<i32>
        }

        let result: Option<Person> = session
            .query("select from OUser where name = ?")
            .positional(&[&"admin"])
            .fetch_one()
            .unwrap();

but it should work since age is optional

Transaction API

The Session should expose transaction API in order to run multiple statement in a single tx which handles begin/commit

The API should look like

session.transaction(|tx| {
 tx.command(...)
})

Change the API OrientDB::connect

Replace the API OrientDB::connect(String, u16)
with OrientDB::connect(options : T) where T is Into<ConnectionOptions> for more ergonomic and flexible way to configure the client

Query builder enhancement

The query builder now expose only the method run for spawning a query/command/script.

For better ergonomic it should expose

  • fetch_one() -> T
  • fetch() -> Vec<T>
  • stream() -> Stream<T> or sync iter() -> impl Iter<T>

with automatic mapping to structs with derive.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.