Skip to content

Commit

Permalink
cycle detected when checking effective visibilities
Browse files Browse the repository at this point in the history
  • Loading branch information
hduoc2003 committed Feb 20, 2024
1 parent 47bc76c commit 9bdcae7
Show file tree
Hide file tree
Showing 33 changed files with 687 additions and 0 deletions.
18 changes: 18 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# gitignore
/result*
/target

# Docker-specific
**/target
*.nix
/.cargo
.direnv
.git
/flake.lock
justfile
## Meta
.dockerignore
Dockerfile*
docker-compose.yml
shared
tempo-data
4 changes: 4 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
HOST=
PORT=
DATABASE=
DATABASE_URL=
27 changes: 27 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
[package]
name = "rust-demo-server"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
axum = "0.7.4"
env_logger = "0.11.2"
serde = { version = "1.0.196", features = ["derive"] }
serde_json = "1.0.113"
tokio = { version = "1.36.0", features = ["full"] }
tracing = { version = "0.1.40", features = ["log"] }
tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
uuid = { version = "1.7.0", features = ["v4"] }
# sqlx = { version = "0.7", features = [ "runtime-tokio", "migrate", "postgres" ] }
dotenv = "0.15.0"
strum = "0.26.1"
strum_macros = "0.26.1"
diesel = { version = "2.1.0", features = ["postgres", "chrono"] }
diesel-async = { version = "0.4.1", features = ["postgres", "bb8", "deadpool"] }
chrono = "0.4.34"
diesel-derive-enum = { version = "2.1.0", features = ["postgres"] }
lazy_static = "1.4.0"
bb8 = "0.8.3"

1 change: 1 addition & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
FROM rust:1.75.0
9 changes: 9 additions & 0 deletions diesel.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# For documentation on how to configure this file,
# see https://diesel.rs/guides/configuring-diesel-cli

[print_schema]
file = "src/schema.rs"
custom_type_derives = ["diesel::query_builder::QueryId"]

[migrations_directory]
dir = "migrations"
20 changes: 20 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
version: '3.9'
services:
db:
image: postgres:15.6
restart: always
# set shared memory limit when using docker-compose
shm_size: 128mb
# or set shared memory limit when deploy via swarm stack
#volumes:
# - type: tmpfs
# target: /dev/shm
# tmpfs:
# size: 134217728 # 128*2^20 bytes = 128Mb
env_file:
- postgres.env
volumes:
- ./postgres-mount:/var/lib/postgresql/data
stdin_open: true
ports:
- "5433:5432"
4 changes: 4 additions & 0 deletions justfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
set shell := ["cmd.exe", "/c"]

dev:
cargo watch -q -w src/ -x run
16 changes: 16 additions & 0 deletions log4rs.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
refresh_rate: 30 seconds
appenders:
stdout:
kind: console
encoder:
kind: json
file:
kind: file
path: "stderr.log"
encoder:
kind: json
root:
level: info
appenders:
- stdout
- file
79 changes: 79 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
use dotenv::dotenv;
use tokio::sync::OnceCell;

use crate::v1::api::{db::database::Database, types::env::ENV, utils::env::get_env};

// Define a struct to represent server configuration
#[derive(Debug)]
struct ServerConfig {
host: String,
port: u16,
}

// Define a struct to represent database configuration
#[derive(Debug)]
struct DatabaseConfig {
url: String,
}

// Define a struct that aggregates server and database configuration
#[derive(Debug)]
pub struct Config {
server: ServerConfig,
db: DatabaseConfig,
}

// Implement methods for the Config struct to access configuration values
impl Config {
// Getter method for the database URL
pub fn db_url(&self) -> &str {
&self.db.url
}

// Getter method for the server host
pub fn server_host(&self) -> &str {
&self.server.host
}

// Getter method for the server port
pub fn server_port(&self) -> u16 {
self.server.port
}
}

// Create a static OnceCell to store the application configuration
pub static CONFIG: OnceCell<Config> = OnceCell::const_new();

// Asynchronously initialize the configuration
async fn init_config() -> Config {
// Load environment variables from a .env file if present
dotenv().ok();

// Create a ServerConfig instance with default values or values from environment variables
let server_config = ServerConfig {
host: get_env(ENV::HOST),
port: get_env(ENV::PORT).parse().unwrap(),
};

// Create a DatabaseConfig instance with a required DATABASE_URL environment variable
let database_config = DatabaseConfig {
url: get_env(ENV::DATABASE_URL),
};

// Create a Config instance by combining server and database configurations
Config {
server: server_config,
db: database_config,
}
}

// Asynchronously retrieve the application configuration, initializing it if necessary
pub async fn config() -> &'static Config {
// Get the configuration from the OnceCell or initialize it if it hasn't been set yet
CONFIG.get_or_init(init_config).await
}

#[derive(Clone)]
pub struct AppState {
pub db: Database
}
31 changes: 31 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
use axum::Router;
use config::{config, AppState};
use v1::api::{db::database::Database, routes::signup, types::{db::DatabaseType, env::ENV}, utils::env::get_env};
// use v1::api::routes::signup::handle_signup;
mod v1;
mod config;
mod schema;

#[tokio::main]
async fn main() {
let config = config().await;

let db: Database = match get_env(ENV::DATABASE).as_str() {
"postgres" => Database::new(DatabaseType::Postgres).await,
"in-memory" => Database::new(DatabaseType::InMemory).await,
x => panic!("Only support postgres and in-memory database, not {}", x)
};


let app_state = AppState {
db
};

let app = Router::new()
.nest("/v1/api", signup::routes())
.with_state(app_state);

let listener = tokio::net::TcpListener::bind(format!("127.0.0.1:{}", get_env(ENV::PORT))).await.unwrap();

axum::serve(listener, app).await.unwrap();
}
123 changes: 123 additions & 0 deletions src/schema.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
// @generated automatically by Diesel CLI.

pub mod sql_types {
#[derive(diesel::query_builder::QueryId, diesel::sql_types::SqlType)]
#[diesel(postgres_type(name = "status_enum"))]
pub struct StatusEnum;
}

diesel::table! {
use diesel::sql_types::*;
use super::sql_types::StatusEnum;

activities (id) {
id -> Int8,
user_id -> Int8,
task_id -> Int8,
#[max_length = 512]
title -> Varchar,
#[max_length = 2048]
description -> Nullable<Varchar>,
status -> StatusEnum,
created_at -> Timestamp,
updated_at -> Nullable<Timestamp>,
planned_start_date -> Nullable<Timestamp>,
planned_end_date -> Nullable<Timestamp>,
actual_start_date -> Nullable<Timestamp>,
actual_end_date -> Nullable<Timestamp>,
content -> Nullable<Text>,
}
}

diesel::table! {
comments (id) {
id -> Int8,
task_id -> Int8,
activity_id -> Nullable<Int8>,
#[max_length = 100]
title -> Varchar,
created_at -> Timestamp,
updated_at -> Nullable<Timestamp>,
content -> Nullable<Text>,
}
}

diesel::table! {
tags (id) {
id -> Int8,
#[max_length = 75]
title -> Varchar,
#[max_length = 100]
slug -> Varchar,
}
}

diesel::table! {
task_tags (task_id, tag_id) {
task_id -> Int8,
tag_id -> Int8,
}
}

diesel::table! {
use diesel::sql_types::*;
use super::sql_types::StatusEnum;

tasks (id) {
id -> Int8,
user_id -> Int8,
created_by -> Int8,
updated_by -> Int8,
#[max_length = 512]
title -> Varchar,
#[max_length = 2048]
description -> Nullable<Varchar>,
status -> StatusEnum,
created_at -> Timestamp,
updated_at -> Nullable<Timestamp>,
planned_start_date -> Nullable<Timestamp>,
planned_end_date -> Nullable<Timestamp>,
actual_start_date -> Nullable<Timestamp>,
actual_end_date -> Nullable<Timestamp>,
content -> Nullable<Text>,
}
}

diesel::table! {
users (id) {
id -> Int8,
is_admin -> Bool,
#[max_length = 50]
first_name -> Nullable<Varchar>,
#[max_length = 50]
last_name -> Nullable<Varchar>,
#[max_length = 50]
username -> Varchar,
#[max_length = 15]
mobile -> Nullable<Varchar>,
#[max_length = 50]
email -> Nullable<Varchar>,
#[max_length = 32]
password_hash -> Varchar,
registered_at -> Timestamptz,
last_login -> Nullable<Timestamp>,
intro -> Nullable<Text>,
}
}

diesel::joinable!(activities -> tasks (task_id));
diesel::joinable!(activities -> users (user_id));
diesel::joinable!(comments -> activities (activity_id));
diesel::joinable!(comments -> tasks (task_id));
diesel::joinable!(task_tags -> tags (tag_id));
diesel::joinable!(task_tags -> tasks (task_id));
diesel::joinable!(tasks -> users (user_id));

diesel::allow_tables_to_appear_in_same_query!(
activities,
comments,
tags,
task_tags,
tasks,
users,
);
1 change: 1 addition & 0 deletions src/v1/api/controllers/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod signup;
32 changes: 32 additions & 0 deletions src/v1/api/controllers/signup.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
use axum::{extract::State, Json};
use serde::{Deserialize, Serialize};

use crate::{config::AppState, v1::api::{db::base::DbBase, utils::errors::ErrorResponse}};

#[derive(Debug, Deserialize)]
struct Request {
username: String,
password: String
}

#[derive(Debug, Serialize)]
struct Response {

}

pub async fn handle_signup(
State(mut state): State<AppState>,
Json(req): Json<Request>
) -> Result<Json<Response>, ErrorResponse> {
match state.db.add_user(&req.username, &req.password).await {
Ok(_) => {
Ok(Json(Response {

}))
},
Err(err) => {
Err(err)
},
}

}
6 changes: 6 additions & 0 deletions src/v1/api/db/base.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
use crate::v1::api::utils::errors::ErrorResponse;

pub trait DbBase {
async fn add_user(&mut self, username: &str, pass: &str) -> Result<(), ErrorResponse>;

}
Loading

0 comments on commit 9bdcae7

Please sign in to comment.