an orm for rust

Overview

Build Status

rustorm

Rustorm

Financial Contributors on Open Collective Latest Version Build Status MIT licensed

Rustorm is an SQL-centered ORM with focus on ease of use on conversion of database types to their appropriate rust type.

Selecting records

use rustorm::{
    DbError,
    FromDao,
    Pool,
    ToColumnNames,
    ToTableName,
};

#[derive(Debug, FromDao, ToColumnNames, ToTableName)]
struct Actor {
    actor_id: i32,
    first_name: String,
}

#[cfg(any(feature="with-postgres", feature = "with-sqlite"))]
fn main() {
    let mut pool = Pool::new();
    #[cfg(feature = "with-sqlite")]
    let db_url = "sqlite://sakila.db";
    #[cfg(feature = "with-postgres")]
    let db_url = "postgres://postgres:p0stgr3s@localhost/sakila";
    let em = pool.em(db_url).unwrap();
    let sql = "SELECT * FROM actor LIMIT 10";
    let actors: Result<Vec<Actor>, DbError> =
        em.execute_sql_with_return(sql, &[]);
    println!("Actor: {:#?}", actors);
    let actors = actors.unwrap();
    assert_eq!(actors.len(), 10);
    for actor in actors {
        println!("actor: {:?}", actor);
    }
}
#[cfg(feature="with-mysql")]
fn main() {
   println!("see examples for mysql usage, mysql has a little difference in the api");
}

Inserting and displaying the inserted records

use chrono::{
    offset::Utc,
    DateTime,
    NaiveDate,
};
use rustorm::{
    DbError,
    FromDao,
    Pool,
    TableName,
    ToColumnNames,
    ToDao,
    ToTableName,
};


#[cfg(any(feature="with-postgres", feature = "with-sqlite"))]
fn main() {
    mod for_insert {
        use super::*;
        #[derive(Debug, PartialEq, ToDao, ToColumnNames, ToTableName)]
        pub struct Actor {
            pub first_name: String,
            pub last_name: String,
        }
    }

    mod for_retrieve {
        use super::*;
        #[derive(Debug, FromDao, ToColumnNames, ToTableName)]
        pub struct Actor {
            pub actor_id: i32,
            pub first_name: String,
            pub last_name: String,
            pub last_update: DateTime<Utc>,
        }
    }

    let mut pool = Pool::new();
    #[cfg(feature = "with-sqlite")]
    let db_url = "sqlite://sakila.db";
    #[cfg(feature = "with-postgres")]
    let db_url = "postgres://postgres:p0stgr3s@localhost/sakila";
    let em = pool.em(db_url).unwrap();
    let tom_cruise = for_insert::Actor {
        first_name: "TOM".into(),
        last_name: "CRUISE".to_string(),
    };
    let tom_hanks = for_insert::Actor {
        first_name: "TOM".into(),
        last_name: "HANKS".to_string(),
    };

    let actors: Result<Vec<for_retrieve::Actor>, DbError> =
        em.insert(&[&tom_cruise, &tom_hanks]);
    println!("Actor: {:#?}", actors);
    assert!(actors.is_ok());
    let actors = actors.unwrap();
    let today = Utc::now().date();
    assert_eq!(tom_cruise.first_name, actors[0].first_name);
    assert_eq!(tom_cruise.last_name, actors[0].last_name);
    assert_eq!(today, actors[0].last_update.date());

    assert_eq!(tom_hanks.first_name, actors[1].first_name);
    assert_eq!(tom_hanks.last_name, actors[1].last_name);
    assert_eq!(today, actors[1].last_update.date());
}
#[cfg(feature="with-mysql")]
fn main() {
   println!("see examples for mysql usage, mysql has a little difference in the api");
}

Rustorm is wholly used by diwata

License: MIT

Contributors

Code Contributors

This project exists thanks to all the people who contribute. [Contribute].

Financial Contributors

Become a financial contributor and help us sustain our community. [Contribute]

Individuals

Organizations

Support this project with your organization. Your logo will show up here with a link to your website. [Contribute]

Comments
  • MySQL support

    MySQL support

    @ivanceras Hi.

    I love this crate more than diesel but not contains mysql support so i added it.

    The big issue

    r2d2-mysql wants connection as mutable for execute query but current signature of Database trait expects immutable. I added Database2, DBPlatform2 and EntityManager2 for keep API for postgres and sqlite. rust-postgres next varsion will be wanted mutable connection maybe (SEE).

    I cloud not implement all of function of Database trait to Database2 trait. But i think it is enough for SELECT, INSERT, UPDATE and DELETE. I hope merge this PR and then implement other function in after.

    Please tell me if there are mistake in my code or thinking.

    Thank you!

    opened by alu 7
  • Can’t compile due to OpenSSL

    Can’t compile due to OpenSSL

    I can’t compile Diwata because Rustorm is using an old version of the crate openssl: https://github.com/sfackler/rust-openssl/issues/987

    Would it be possible to bump up the version of openssl in the depencecies?

    opened by batisteo 6
  • Some neat picks

    Some neat picks

    This PR adds two modifications:

    1. Add NaiveDateTime to Value conversion
    2. Use local dependencies of dao and codegen. This is important because currently rustorm depends on crate.io distributed dao & codegen. This makes depending on the git branch impossible. Thus generally considered as anti-pattern.

    By the way, [replace] is not used when rustorm is introduced as a lib dependency. So it's also removed.

    opened by zimond 3
  • implement std Error for error types

    implement std Error for error types

    This could help errors from this crate work better with general error handling crates.

    Currently the most suitable solution would be using the thiserror crate. Or, we could manulay implement std::error::Error for all the errors exported from rustorm.

    Which is your fav? I can make a PR based on the choice.

    opened by zimond 3
  • Option with custom types

    Option with custom types

    @ivanceras Hi! Thank you for merging my PR :D. But i got new problem :(.

    We have defined several custom type such as Id(i64).

    It can be used as query parameter if we defined impl rustorm::ToValue for Id.

    impl rustorm::ToValue for Id {
        fn to_value(&self) -> rustorm::Value {
            rustorm::Value::Bigint(self.0)
        }
    }
    
    #[derive(Debug, FromDao)]
    struct R {}
    
    let _: Vec<R> = em
        .execute_sql_with_return("SELECT id FROM table id = ?", &[&Id(99)])
        .unwrap();
    

    It can be used as result type if we defined impl From<&rustorm::Value> for Id.

    impl From<&rustorm::Value> for Id {
        fn from(v: &rustorm::Value) -> Id {
            match v {
                rustorm::Value::Bigint(v) => Id(*v),
                _ => panic!("unable to convert"),
            }
        }
    }
    
    #[derive(Debug, FromDao)]
    struct R {
        e: Id,
    }
    
    let _: Vec<R> = em
        .execute_sql_with_return("SELECT id FROM table", &[])
        .unwrap();
    

    But we can't be used if it wrapted by Option because From and ToValue are external trait, and Option is external type.

    The newtype pattern such as Id(i64) is general in Rust so I think it ’s worth making it available. I think need new trait such as FromValue for instead of From. But it's will makes broken changes.

    What do you think the idea?

    opened by alu 2
  • Problem in Option<Enum>

    Problem in Option

    Hi.

    We want to use enum as query result and parameter so we implemented traits to enum. But it does not work when contain in Option because From<Value> for Option<Enum> does not implemented . As you know we cannot implement the trait because Value and Option are outside crate both. I make Opt<Option<T>> and avoid it, are there more happy solution?

    Example.

    use rustorm::codegen::{ToColumnNames, ToDao, ToTableName};
    
    #[derive(Debug)]
    enum ExampleEnum {
        A,
        B,
    }
    
    impl rustorm::ToValue for ExampleEnum {
        fn to_value(&self) -> rustorm::Value {
            self.into()
        }
    }
    
    impl From<&ExampleEnum> for rustorm::Value {
        fn from(from: &ExampleEnum) -> rustorm::Value {
            match from {
                ExampleEnum::A => "a",
                ExampleEnum::B => "b",
            }
            .into()
        }
    }
    
    impl From<&rustorm::Value> for ExampleEnum {
        fn from(value: &rustorm::Value) -> Self {
            match value {
                rustorm::Value::Text(value) => match value.as_str() {
                    "a" => ExampleEnum::A,
                    "b" => ExampleEnum::B,
                    _ => panic!("unkonwn value"),
                },
                _ => panic!("unspported type"),
            }
        }
    }
    
    // OK!
    #[derive(Debug, ToDao, ToColumnNames, ToTableName)]
    struct ExampleStruct {
        value: ExampleEnum,
    }
    
    // NG...
    #[derive(Debug, ToDao, ToColumnNames, ToTableName)]
    struct ExampleOptionStruct {
        value: Option<ExampleEnum>,
    }
    
    opened by alu 2
  • How execute SQL

    How execute SQL

    @ivanceras Hi.

    I want to execute SQL that does not need return value like below.

    UPDATE user set name = ? where id = ?
    

    I looked for match to the objective, but i can't found it. What should I use?

    opened by alu 2
  • Upgrade rusqlite and r2d2_sqlite

    Upgrade rusqlite and r2d2_sqlite

    Got a conflict between this and refinery because of mismatching versions so I updated rusqlite and r2d2_sqlite to the newest versions. All the tests still pass. :)

    opened by edmellum 1
  • Always creates new pool in call em()

    Always creates new pool in call em()

    @ivanceras Hi!

    Pool::em() calls ensure(), so it calls init_pool always finally for now. I thinks it's not necessary and happens problems sometime maybe.

    opened by alu 1
  • add numeric to bool conversion

    add numeric to bool conversion

    Add support numeric value to bool conversion

    Bool value be expressed as numeric value in MySQL.

    Add support ToDato, ToTableName, ToColumnNames to borrowed field contained struct

    We need insert values with borrowed value because we do not want to clone String. For example.

    fn insert(mut em: rustorm::EntityManagerMut, message: &str) {
        #[derive(Debug, ToDao, ToTableName, ToColumnNames)]
        struct Row<'b> {
            message: &'b str,
        };
    
        em.single_insert(&Row { message }).unwrap();
    }
    
    opened by alu 1
  • Compiling bug

    Compiling bug

    mike@DESKTOP-IU99086:~/sappworks/rustorm$ cargo build
       Compiling rustorm v0.10.7 (/home/mike/sappworks/rustorm)
    error[E0599]: no method named `safe_name` found for type `dao::TableName` in the current scope
      --> src/table.rs:29:19
       |
    29 |         self.name.safe_name()
       |                   ^^^^^^^^^
    
    error[E0599]: no method named `safe_complete_name` found for type `dao::TableName` in the current scope
      --> src/table.rs:33:19
       |
    33 |         self.name.safe_complete_name()
       |                   ^^^^^^^^^^^^^^^^^^
       |
       = help: did you mean `complete_name`?
    
    error: aborting due to 2 previous errors
    
    For more information about this error, try `rustc --explain E0599`.
    error: Could not compile `rustorm`.
    
    To learn more, run the command again with --verbose.
    mike@DESKTOP-IU99086:~/sappworks/rustorm$ rustc -V
    rustc 1.30.0-nightly (63d51e89a 2018-09-28)
    
    
    
    opened by miketang84 1
  • support for int/bigint arrays

    support for int/bigint arrays

    I was trying to use this but ran into issues with some of my columns having int and bigint arrays, tried to also hack around it by implementing FromValue myself but ran into more issues with Array::Int being only 32bits.

    opened by jonas747 1
  • Derive macros aren't usable unless rustorm_dao is added as a separate dependency.

    Derive macros aren't usable unless rustorm_dao is added as a separate dependency.

    rustorm version: 0.17 rust version: 1.45.2

    Attempting to use any of the derive macros provided by rustorm (ToDao, FromDao, ToTableName, ToColumnNames) will fail to compile with the following error message: error[E0433]: failed to resolve: use of undeclared type or module `rustorm_dao`

    Adding rustorm_dao = "0.5" as a dependency in Cargo.toml fixes this but since rustorm_dao is already a dependency of rustorm and this is not mentioned anywhere in the readme I am guessing this isn't supposed to be the case? If this is expected, it should probably be mentioned somewhere.

    good first issue 
    opened by ghost 1
Owner
Jovansonlee Cesar
I'm for hire. If your company uses rust and interested in one of my projects, please recommend me.
Jovansonlee Cesar
🐚 An async & dynamic ORM for Rust

SeaORM ?? An async & dynamic ORM for Rust SeaORM SeaORM is a relational ORM to help you build web services in Rust with the familiarity of dynamic lan

SeaQL 3.5k Jan 6, 2023
Diesel - A safe, extensible ORM and Query Builder for Rust

A safe, extensible ORM and Query Builder for Rust API Documentation: latest release – master branch Homepage Diesel gets rid of the boilerplate for da

Takayuki Maeda 0 Aug 31, 2020
Ormlite - An ORM in Rust for developers that love SQL.

ormlite ormlite is an ORM in Rust for developers that love SQL. It provides the following, while staying close to SQL, both in syntax and performance:

Kurt Wolf 28 Jan 1, 2023
Diesel - ORM and Query Builder for Rust

A safe, extensible ORM and Query Builder for Rust API Documentation: latest release – master branch Homepage Diesel gets rid of the boilerplate for da

Diesel 9.7k Jan 6, 2023
Rust High Performance compile-time ORM(RBSON based)

WebSite | 简体中文 | Showcase | 案例 A highly Performant,Safe,Dynamic SQL(Compile time) ORM framework written in Rust, inspired by Mybatis and MybatisPlus.

rbatis 1.7k Jan 7, 2023
ORM for ScyllaDb and Cassandra

ScyllaDb/Cassandra Object-Relation Mapper Features This library contains several crates with the following features: Automatic map tables to Rust stru

null 36 Jan 1, 2023
CRUD system of book-management with ORM and JWT for educational purposes.

Book management English | 中文 Required Rust MySQL 5.7 Usage Execute init.sql to create tables. Set environment variable DATABASE_URL and JWT_SECRET in

null 32 Dec 28, 2022
Bind the Prisma ORM query engine to any programming language you like ❤️

Prisma Query Engine C API Bind the Prisma ORM query engine to any programming language you like ❤️ Features Rust bindings for the C API Static link li

Prisma ORM for community 10 Dec 15, 2022
Bind the Prisma ORM query engine to any programming language you like ❤️

Prisma Query Engine C API Bind the Prisma ORM query engine to any programming language you like ❤️ Features Rust bindings for the C API Static link li

Odroe 6 Sep 9, 2022
🧰 The Rust SQL Toolkit. An async, pure Rust SQL crate featuring compile-time checked queries without a DSL. Supports PostgreSQL, MySQL, SQLite, and MSSQL.

SQLx ?? The Rust SQL Toolkit Install | Usage | Docs Built with ❤️ by The LaunchBadge team SQLx is an async, pure Rust† SQL crate featuring compile-tim

launchbadge 7.6k Dec 31, 2022
Redis re-implemented in Rust.

rsedis Redis re-implemented in Rust. Why? To learn Rust. Use Cases rsedis does not rely on UNIX-specific features. Windows users can run it as a repla

Sebastian Waisbrot 1.6k Jan 6, 2023
A generic connection pool for Rust

r2d2 A generic connection pool for Rust. Documentation Opening a new database connection every time one is needed is both inefficient and can lead to

Steven Fackler 1.2k Jan 8, 2023
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
Cassandra DB native client written in Rust language. Find 1.x versions on https://github.com/AlexPikalov/cdrs/tree/v.1.x Looking for an async version? - Check WIP https://github.com/AlexPikalov/cdrs-async

CDRS CDRS is looking for maintainers CDRS is Apache Cassandra driver written in pure Rust. ?? Looking for an async version? async-std https://github.c

Alex Pikalov 338 Jan 1, 2023
Cassandra (CQL) driver for Rust, using the DataStax C/C++ driver under the covers.

cassandra-cpp This is a maintained Rust project that exposes the DataStax cpp driver at https://github.com/datastax/cpp-driver/ in a somewhat-sane cra

null 93 Jan 7, 2023
CouchDB client-side library for the Rust programming language

Chill Chill is a client-side CouchDB library for the Rust programming language, available on crates.io. It targets Rust Stable. Chill's three chief de

null 35 Jun 26, 2022
Sofa - CouchDB for Rust

Sofa - CouchDB for Rust Documentation Here: http://docs.rs/sofa Installation [dependencies] sofa = "0.6" Description This crate is an interface to Cou

66 Origin 40 Feb 11, 2022
⚡🦀 🧨 make your rust types fit DynamoDB and visa versa

?? ?? dynomite dynomite makes DynamoDB fit your types (and visa versa) Overview Goals ⚡ make writing dynamodb applications in rust a productive experi

Doug Tangren 197 Dec 15, 2022
A Rust client for the ElasticSearch REST API

rs-es Introduction An ElasticSearch client for Rust via the REST API. Targetting ElasticSearch 2.0 and higher. Other clients For later versions of Ela

Ben Ashford 218 Dec 27, 2022