Skip to content

42ByteLabs/geekorm

Repository files navigation

GeekORM

GitHub Crates.io Version Crates.io Downloads (recent) GitHub Stars GitHub Issues Licence

Overview

GeekORM is a simple Object Relation Mapper for empowering your Rust development.

✨ Features

  • Focus on simplicity
  • Rely on Derive Macros to generate code for your structs
    • Using Table
    • Using Data
  • Dynamically build queries
    • Select, Create, Update, and Insert queries
  • Extensive crate features
  • Field Attribute Helpers
    • foreign_key: Set the foreign key for a join
    • rand: Generate random strings (set lenght, set prefix, set enviroment)
    • hash or password: Generate secure Hashes of passwords (set algorithm)
  • Support for Backends
  • Documentation

📦 Usage

You can install the library from crates.io:

cargo add geekorm

Manual - GitHub

cargo install --git https://github.com/42ByteLabs/geekorm

🏃 Getting Started

Once you have installed geekorm, you can start using the derive macros like the following:

use anyhow::Result;
use geekorm::prelude::*;

#[derive(Table, Debug, Default, serde::Serialize, serde::Deserialize)]
struct Users {
    #[geekorm(primary_key, auto_increment)]
    id: PrimaryKeyInteger,

    #[geekorm(unique)]
    username: String,

    #[geekorm(hash)]
    password: String,

    #[geekorm(new = "UserType::User")]
    user_type: UserType,

    #[geekorm(new = "chrono::Utc::now()")]
    created_at: chrono::DateTime<chrono::Utc>,

    postcode: Option<String>,
}

#[derive(Data, Debug, Default, Clone)]
enum UserType {
    Admin,
    #[default]
    User,
}

#[tokio::main]
async fn main() -> Result<()> {
    // Setup the database and connection
    let db = libsql::Builder::new_local(":memory:").build().await
        .expect("Failed to create database");
    let connection = db.connect()
        .expect("Failed to connect to database");

    // Create the table in the database
    Users::create_table(&connection).await?;

    // Creating a new User
    let mut user = Users::new("GeekMasher", "ThisIsNotMyPassword");
    // Saving the new User in the database
    user.save(&connection).await?;
    // Print the Primary Key value set by the database (auto_increment)
    println!("User ID: {:?}", user.id);

    // Updating the User
    user.user_type = UserType::Admin;
    user.update(&connection).await?;

    // Fetch the Admin Users
    let admin_users = Users::fetch_by_user_type(&connection, UserType::Admin).await?;
    println!("Admin Users: {:?}", admin_users);

    // Helper functions built right into the struct by GeekORM
    user.hash_password("ThisIsStillNotMyPassword")?;

    // Go back to basics and build your own queries dynamically using
    // the QueryBuilder built into GeekORM
    let query = Users::query_select()
        .where_eq("username", "GeekMasher")
        .order_by("id", geekorm::QueryOrder::Desc)
        .limit(1)
        .build()?;

    // Execute the query and return the results
    let users = Users::query(&connection, query).await?;
    println!("Users: {:?}", users);

    Ok(())
}

🏄 Create Features

There are a number of opt-in features supported by GeekORM. Features can be added either using cargo add geekorm -F all or added them directly in your Cargo.toml file.

  • all: Enable all the major stable features
  • new: Generate Table::new(...) functions
  • helpers: Generate a number of helper functions
    • Select Table::select_by_primary_key()
    • Select column Table::select_by_{field}()
  • rand: Support Generating random strings
  • hash: Support Generating password hashes
  • Backends
    • libsql: Add LibSQL backend support

🧑‍🤝‍🧑 Maintainers / Contributors

Mathew Payne
Mathew Payne

💻 👀
Cale
Cale

🎨

🦸 Support

Please create GitHub Issues if there are bugs or feature requests.

This project uses Semantic Versioning (v2) and with major releases, breaking changes will occur.

📓 License

This project is licensed under the terms of the MIT open source license. Please refer to MIT for the full terms.