Skip to content

Initial poc evaluating Rust tech stack for project use #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Oct 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3,050 changes: 2,848 additions & 202 deletions Cargo.lock

Large diffs are not rendered by default.

7 changes: 5 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ name = "refactor_platform_rs"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[workspace]
members = [".", "api", "entity", "migration"]

[dependencies]
axum = "0.6.20"
api = { path = "api" }
clap = { version = "4.4.6", features = ["cargo", "derive", "env"] }

28 changes: 28 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Basic local DB setup and management

## Set Up Database (running commands against postgres server.)
```sql
--create user
CREATE USER refactor_rs WITH PASSWORD 'password';
--create schema
CREATE SCHEMA IF NOT EXISTS refactor_platform_rs;
--Check to see that the schema exists
SELECT schema_name FROM information_schema.schemata;
--Grant schema access to user
GRANT CREATE ON SCHEMA public TO refactor_rs;
```

## Generate new migration
```bash
sea-orm-cli migrate generate your_table_name
```

## Run migrations (Assumes database name is postgres)
```bash
DATABASE_URL=postgres://refactor_rs:password@localhost:5432/postgres sea-orm-cli migrate up -s refactor_platform_rs
```

## Generate Entity from Database
```bash
DATABASE_URL=postgres://refactor_rs:password@localhost:5432/postgres sea-orm-cli generate entity -s refactor_platform_rs -o entity/src
```
15 changes: 15 additions & 0 deletions api/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[package]
name = "api"
version = "0.1.0"
edition = "2021"

[dependencies]
entity = { path = "../entity" }
axum = "0.6.20"
# used to block for testing
futures = "0.3.28"
log = "0.4.20"
serde_json = "1.0.107"
service = { path = "../service" }
tokio = { version = "1.32.0", features = ["full"] }
tower = "0.4.13"
110 changes: 110 additions & 0 deletions api/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
use serde_json::json;
use service::sea_orm::{
entity::prelude::*, query::*, ActiveValue, ConnectOptions, Database, DatabaseConnection, DbErr,
};
use tokio::time::Duration;

use entity::{coaching_relationship, organization, user};

//use refactor_platform_rs::config::Config;

#[tokio::main]
async fn start() {
let mut opt = ConnectOptions::new("postgres://refactor_rs:password@localhost:5432/postgres");
opt.max_connections(100)
.min_connections(5)
.connect_timeout(Duration::from_secs(8))
.acquire_timeout(Duration::from_secs(8))
.idle_timeout(Duration::from_secs(8))
.max_lifetime(Duration::from_secs(8))
.sqlx_logging(true)
.sqlx_logging_level(log::LevelFilter::Info)
.set_schema_search_path("refactor_platform_rs"); // Setting default PostgreSQL schema

let db = Database::connect(opt)
.await
.expect("Database connection failed");

seed_database(db).await;
}

async fn seed_database(db: DatabaseConnection) {
let organization = organization::ActiveModel::from_json(json!({
"name": "Jim Hodapp Coaching",
}))
.unwrap();

assert_eq!(
organization,
organization::ActiveModel {
id: ActiveValue::NotSet,
name: ActiveValue::Set("Jim Hodapp Coaching".to_owned()),
}
);

let persisted_org: organization::Model = organization.insert(&db).await.unwrap();

let queried_org: Option<organization::Model> =
organization::Entity::find_by_id(persisted_org.id)
.one(&db)
.await
.unwrap();

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

let caleb = user::ActiveModel::from_json(json!({
"email": "calebbourg2@gmail.com",
"first_name": "Caleb",
"last_name": "Bourg"
}))
.unwrap();

let persisted_caleb = caleb.insert(&db).await.unwrap();

let queried_caleb: Option<user::Model> = user::Entity::find_by_id(persisted_caleb.id)
.one(&db)
.await
.unwrap();

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

let jim = user::ActiveModel::from_json(json!({
"email": "jim@jimhodappcoaching.com",
"first_name": "Jim",
"last_name": "Hodapp"
}))
.unwrap();

let persisted_jim = jim.insert(&db).await.unwrap();

let queried_jim: Option<user::Model> = user::Entity::find_by_id(persisted_jim.id)
.one(&db)
.await
.unwrap();

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

let coaching_relationship = coaching_relationship::ActiveModel::from_json(json!({
"coach_id": queried_jim.unwrap().id.to_string(),
"coachee_id": queried_caleb.unwrap().id.to_string(),
"organization_id": queried_org.unwrap().id.to_string()
}))
.unwrap();

let persisted_coaching_relationship = coaching_relationship.insert(&db).await.unwrap();

let queried_coaching_relationship: Option<coaching_relationship::Model> =
coaching_relationship::Entity::find_by_id(persisted_coaching_relationship.id)
.one(&db)
.await
.unwrap();

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

pub fn main() {
start()
}
15 changes: 15 additions & 0 deletions entity/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[package]
name = "entity"
version = "0.1.0"
edition = "2021"

[lib]
name = "entity"
path = "src/lib.rs"

[dependencies]
serde = { version = "1", features = ["derive"] }


[dependencies.sea-orm]
version = "0.12.3"
52 changes: 52 additions & 0 deletions entity/src/coaching_relationship.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.3

use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize};

#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Deserialize, Serialize)]
#[sea_orm(
schema_name = "refactor_platform_rs",
table_name = "coaching_relationships"
)]
pub struct Model {
#[sea_orm(primary_key)]
#[serde(skip_deserializing)]
pub id: i32,
pub coachee_id: String,
pub coach_id: String,
pub organization_id: String,
}

#[derive(Copy, Clone, Debug, EnumIter)]
pub enum Relation {
Organization,
Coach,
Coachee,
}

impl RelationTrait for Relation {
fn def(&self) -> RelationDef {
match self {
Self::Organization => Entity::belongs_to(super::organization::Entity)
.from(Column::OrganizationId)
.to(super::organization::Column::Id)
.into(),
Self::Coach => Entity::belongs_to(super::user::Entity)
.from(Column::CoachId)
.to(super::user::Column::Id)
.into(),
Self::Coachee => Entity::belongs_to(super::user::Entity)
.from(Column::CoacheeId)
.to(super::user::Column::Id)
.into(),
}
}
}

impl Related<super::organization::Entity> for Entity {
fn to() -> RelationDef {
Relation::Organization.def()
}
}

impl ActiveModelBehavior for ActiveModel {}
3 changes: 3 additions & 0 deletions entity/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pub mod coaching_relationship;
pub mod organization;
pub mod user;
30 changes: 30 additions & 0 deletions entity/src/links.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
pub struct UserToOrganizationAsCoach;

impl Linked for UserToOrganizationAsCoach {
type FromEntity = User::Entity;

type ToEntity = Organization::Entity;

fn link(&self) -> Vec<RelationDef> {
vec![
coaching_relationship::Relation::Coach.def().rev(),
coaching_relationship::Relation::Organization.def(),
]
}
}

pub struct UserToOrganizationAsCoachee;

impl Linked for UserToOrganizationAsCoachee {
type FromEntity = User::Entity;

type ToEntity = Organization::Entity;

fn link(&self) -> Vec<RelationDef> {
vec![
coaching_relationship::Relation::Coachee.def().rev(),
coaching_relationship::Relation::Organization.def(),
]
}
}

7 changes: 7 additions & 0 deletions entity/src/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.3

pub mod prelude;

pub mod coaching_relationship;
pub mod organization;
pub mod user;
30 changes: 30 additions & 0 deletions entity/src/organization.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.3

use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize};

#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Deserialize, Serialize)]
#[sea_orm(schema_name = "refactor_platform_rs", table_name = "organizations")]
pub struct Model {
#[sea_orm(primary_key)]
#[serde(skip_deserializing)]
pub id: i32,
pub name: String,
}

#[derive(Copy, Clone, Debug, EnumIter)]
pub enum Relation {
CoachingRelationship,
}

impl RelationTrait for Relation {
fn def(&self) -> RelationDef {
match self {
Self::CoachingRelationship => {
Entity::has_many(super::coaching_relationship::Entity).into()
}
}
}
}

impl ActiveModelBehavior for ActiveModel {}
5 changes: 5 additions & 0 deletions entity/src/prelude.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.3

pub use super::coaching_relationships::Entity as CoachingRelationships;
pub use super::organizations::Entity as Organizations;
pub use super::users::Entity as Users;
20 changes: 20 additions & 0 deletions entity/src/user.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.12.3

use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize};

#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Deserialize, Serialize)]
#[sea_orm(schema_name = "refactor_platform_rs", table_name = "users")]
pub struct Model {
#[sea_orm(primary_key)]
#[serde(skip_deserializing)]
pub id: i32,
pub email: String,
pub first_name: String,
pub last_name: String,
}

#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {}

impl ActiveModelBehavior for ActiveModel {}
19 changes: 19 additions & 0 deletions migration/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[package]
name = "migration"
version = "0.1.0"
edition = "2021"
publish = false

[lib]
name = "migration"
path = "src/lib.rs"

[dependencies]
async-std = { version = "1", features = ["attributes", "tokio1"] }

[dependencies.sea-orm-migration]
version = "0.12.0"
features = [
"runtime-tokio-rustls",
"sqlx-postgres",
]
Loading