Crates.io | atmosphere |
lib.rs | atmosphere |
version | 0.3.0 |
source | src |
created_at | 2023-07-01 14:20:31.609883 |
updated_at | 2024-06-29 15:16:05.604939 |
description | A lightweight sql framework for sustainable database reliant systems |
homepage | |
repository | https://github.com/helsing-ai/atmosphere |
max_upload_size | |
id | 905546 |
size | 2,002,435 |
Atmosphere is a lightweight SQL framework designed for sustainable, database-reliant systems. It leverages Rust's powerful type and macro systems to derive SQL schemas from your rust struct definitions into an advanced trait system.
atmosphere::testing
use atmosphere::prelude::*;
#[derive(Schema)]
#[table(schema = "public", name = "user")]
struct User {
#[sql(pk)]
id: i32,
name: String,
#[sql(unique)]
email: String,
}
#[derive(Schema)]
#[table(schema = "public", name = "post")]
struct Post {
#[sql(pk)]
id: i32,
#[sql(fk -> User, rename = "author_id")]
author: i32,
#[sql(unique)]
title: String,
}
#[tokio::main]
async fn main() -> sqlx::Result<()> {
let pool = atmosphere::Pool::connect(&std::env::var("DATABASE_URL").unwrap()).await?;
// CRUD operations
let user = User { id: 0, name: "demo".to_owned(), email: "some@email.com".to_owned(), };
user.save(&pool).await?;
user.delete(&pool).await?;
user.create(&pool).await?;
// Field Queries
assert_eq!(
User::read(&pool, &0).await?,
User::find_by_email(&pool, "some@email.com").await?.unwrap()
);
// Relationships
Post { id: 0, author: 0, title: "test".to_owned() }
.save(&pool)
.await?;
Post::find_by_author(&pool, &0).await?;
Post::delete_by_author(&pool, &0).await?;
// Inter-Table Operations
Post { id: 1, author: 0, title: "test1".to_owned() }
.author(&pool).await?;
user.posts(&pool).await?;
user.delete_posts(&pool).await?;
Ok(())
}
Atmosphere introspects the User
and Post
structs at compile time and
generates const
available type information about the schema into the Table
trait.
Table
, Column
, Relation
..)Schema
)#[sql(pk)]
, #[sql(fk -> Model)]
and so on)#[table]
)atmosphere::hooks
miette
validator
support#[virtual = "<sql>"]
)#[query]
)Generate GraphQL + HTTP Servers?
Generate Graphs
Given a struct Model
that derives its atmosphere schema using
#[derive(Schema)]
and #[table]
:
use atmosphere::prelude::*;
#[derive(Schema)]
#[table(schema = "public", name = "model")]
struct Model {
#[sql(pk)]
id: i32,
a: String,
#[sql(unique)]
b: String,
}
Atmosphere is able to derive and generate the following queries:
atmosphere::Create
Model::create
atmosphere::Read
Model::read
: read a Model
by its primary key, returning a Model
.Model::find
: find a Model
by its primary key, returning an Option<Model>
.Model::read_all
: read all Model
s, returning a Vec<Model>
.Model::reload
atmosphere::Update
Model::update
Model::upsert
atmosphere::Delete
Model::delete
Model::delete_by
Each struct field that is marked with #[sql(unique)]
becomes queryable.
In the above example b
was marked as unique so atmosphere implements:
Model::find_by_b
: find a Model
by its b
field, returning an Option<Model>
.Model::delete_by_b
: delete a Model
by its b
field.Given that a model contains fields are marked as a foreign key / point to
another atmosphere::Table
atmosphere – for example:
#[derive(Schema)]
#[table(schema = "public", name = "submodel")]
struct Submodel {
#[sql(pk)]
id: i32,
#[sql(fk -> Model)]
super: i32,
}
Atmosphere is able to generate utility queries to move across Table
boundaries:
Model::submodels
Model::delete_submodels
Submodel::model
Submodel::find_by_model
Submodel::delete_by_model
Note that the function names contain
model
andsubmodel
– they are derived from the respective struct names.
We welcome contributions! Please see our contribution guidelines for more details.
Atmosphere is licensed under Apache 2.0.