Experiment with axum / diesel
This commit is contained in:
		
							parent
							
								
									1b4db04895
								
							
						
					
					
						commit
						dfdc361d01
					
				
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										12
									
								
								Cargo.toml
								
								
								
								
							
							
						
						
									
										12
									
								
								Cargo.toml
								
								
								
								
							| 
						 | 
					@ -4,3 +4,15 @@ version = "0.1.0"
 | 
				
			||||||
edition = "2021"
 | 
					edition = "2021"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[dependencies]
 | 
					[dependencies]
 | 
				
			||||||
 | 
					axum = "0.7.7"
 | 
				
			||||||
 | 
					deadpool-diesel = {version = "0.6.1", features = ["sqlite"]}
 | 
				
			||||||
 | 
					diesel = { version = "2.2.4", features = ["sqlite", "returning_clauses_for_sqlite_3_35"] }
 | 
				
			||||||
 | 
					dotenvy = "0.15.7"
 | 
				
			||||||
 | 
					libsqlite3-sys = {version="0.30.1", features = ["bundled"]}
 | 
				
			||||||
 | 
					serde = {version="1.0.214", features = ["derive"]}
 | 
				
			||||||
 | 
					tokio = {version="1.41.0", features = ["full"]}
 | 
				
			||||||
 | 
					tracing = "0.1.40"
 | 
				
			||||||
 | 
					tracing-subscriber = {version="0.3.18", features = ["env-filter"]}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[dev-dependencies]
 | 
				
			||||||
 | 
					diesel_migrations = "2.2.0"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,9 @@
 | 
				
			||||||
 | 
					FROM rust:alpine3.19
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RUN apk add --no-cache musl-dev
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ADD ./ /app
 | 
				
			||||||
 | 
					WORKDIR /app
 | 
				
			||||||
 | 
					RUN cargo build --release
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CMD [ "/app/target/release/work-timer" ]
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,10 @@
 | 
				
			||||||
 | 
					# 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", "Clone"]
 | 
				
			||||||
 | 
					filter = { only_tables = ["users"] }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[migrations_directory]
 | 
				
			||||||
 | 
					dir = "/home/server/Workspace/Projects/WorkTimer/Server/migrations"
 | 
				
			||||||
| 
						 | 
					@ -7,7 +7,6 @@
 | 
				
			||||||
            inputs.nixpkgs-lib.follows = "nixpkgs";
 | 
					            inputs.nixpkgs-lib.follows = "nixpkgs";
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					 | 
				
			||||||
    outputs = inputs @ {flake-parts, ...}:
 | 
					    outputs = inputs @ {flake-parts, ...}:
 | 
				
			||||||
        flake-parts.lib.mkFlake {inherit inputs;} {
 | 
					        flake-parts.lib.mkFlake {inherit inputs;} {
 | 
				
			||||||
            systems = ["x86_64-linux" "aarch64-linux"];
 | 
					            systems = ["x86_64-linux" "aarch64-linux"];
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1 @@
 | 
				
			||||||
 | 
					DROP TABLE users
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,4 @@
 | 
				
			||||||
 | 
					CREATE TABLE users (
 | 
				
			||||||
 | 
					  id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
 | 
				
			||||||
 | 
					  username VARCHAR NOT NULL
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
							
								
								
									
										80
									
								
								src/main.rs
								
								
								
								
							
							
						
						
									
										80
									
								
								src/main.rs
								
								
								
								
							| 
						 | 
					@ -1,3 +1,79 @@
 | 
				
			||||||
fn main() {
 | 
					use diesel::prelude::*;
 | 
				
			||||||
    println!("Hello, world!");
 | 
					use dotenvy::dotenv;
 | 
				
			||||||
 | 
					use self::models::*;
 | 
				
			||||||
 | 
					use std::env;
 | 
				
			||||||
 | 
					use axum::{
 | 
				
			||||||
 | 
					    routing::{get, post},
 | 
				
			||||||
 | 
					    http::StatusCode,
 | 
				
			||||||
 | 
					    Json, Router,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					use serde::{Deserialize, Serialize};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub mod models;
 | 
				
			||||||
 | 
					pub mod schema;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn establish_connection() -> SqliteConnection {
 | 
				
			||||||
 | 
					    dotenv().ok();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let database_url = env::var("SQLITE_DATABASE_URL")
 | 
				
			||||||
 | 
					        .or_else(|_| env::var("DATABASE_URL"))
 | 
				
			||||||
 | 
					        .expect("DATABASE_URL must be set");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    SqliteConnection::establish(&database_url)
 | 
				
			||||||
 | 
					        .unwrap_or_else(|_| panic!("Error connecting to {}", database_url))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[tokio::main]
 | 
				
			||||||
 | 
					async fn main() {
 | 
				
			||||||
 | 
					    use self::schema::users::dsl::*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // initialize tracing
 | 
				
			||||||
 | 
					    tracing_subscriber::fmt::init();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let connection = &mut establish_connection();
 | 
				
			||||||
 | 
					    let results = users
 | 
				
			||||||
 | 
					        .limit(5)
 | 
				
			||||||
 | 
					        .select(User::as_select())
 | 
				
			||||||
 | 
					        .load(connection)
 | 
				
			||||||
 | 
					        .expect("Error loading users");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    println!("Displaying {} users", results.len());
 | 
				
			||||||
 | 
					    for user in results {
 | 
				
			||||||
 | 
					        println!("{:?}", user)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // build our application with a route
 | 
				
			||||||
 | 
					    let app = Router::new()
 | 
				
			||||||
 | 
					        // `GET /` goes to `root`
 | 
				
			||||||
 | 
					        .route("/", get(root))
 | 
				
			||||||
 | 
					        // `POST /users` goes to `create_user`
 | 
				
			||||||
 | 
					        .route("/users", post(create_user));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // run our app with hyper, listening globally on port 3000
 | 
				
			||||||
 | 
					    let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
 | 
				
			||||||
 | 
					    axum::serve(listener, app).await.unwrap();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// basic handler that responds with a static string
 | 
				
			||||||
 | 
					async fn root() -> &'static str {
 | 
				
			||||||
 | 
					    "Hello, World!"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					async fn create_user(
 | 
				
			||||||
 | 
					    // this argument tells axum to parse the request body
 | 
				
			||||||
 | 
					    // as JSON into a `CreateUser` type
 | 
				
			||||||
 | 
					    Json(payload): Json<NewUser>,
 | 
				
			||||||
 | 
					) -> (StatusCode, Json<User>) {
 | 
				
			||||||
 | 
					    let connection = &mut establish_connection();
 | 
				
			||||||
 | 
					    use crate::schema::users;
 | 
				
			||||||
 | 
					    // insert your application logic here
 | 
				
			||||||
 | 
					    let user = diesel::insert_into(users::table)
 | 
				
			||||||
 | 
					        .values(&payload)
 | 
				
			||||||
 | 
					        .returning(User::as_returning())
 | 
				
			||||||
 | 
					        .get_result(connection)
 | 
				
			||||||
 | 
					        .expect("Error saving new user");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // this will be converted into a JSON response
 | 
				
			||||||
 | 
					    // with a status code of `201 Created`
 | 
				
			||||||
 | 
					    (StatusCode::CREATED, Json(user))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,18 @@
 | 
				
			||||||
 | 
					use diesel::prelude::*;
 | 
				
			||||||
 | 
					use serde::{Deserialize, Serialize};
 | 
				
			||||||
 | 
					use super::schema::users;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Queryable, Selectable, Serialize, Deserialize, Debug)]
 | 
				
			||||||
 | 
					#[diesel(table_name = crate::schema::users)]
 | 
				
			||||||
 | 
					#[diesel(check_for_backend(diesel::sqlite::Sqlite))]
 | 
				
			||||||
 | 
					pub struct User {
 | 
				
			||||||
 | 
					    pub id: i32,
 | 
				
			||||||
 | 
					    pub username: String,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Insertable, Serialize, Deserialize, Debug)]
 | 
				
			||||||
 | 
					#[diesel(table_name = users)]
 | 
				
			||||||
 | 
					pub struct NewUser {
 | 
				
			||||||
 | 
					    pub username: String,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,8 @@
 | 
				
			||||||
 | 
					// @generated automatically by Diesel CLI.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					diesel::table! {
 | 
				
			||||||
 | 
					    users (id) {
 | 
				
			||||||
 | 
					        id -> Integer,
 | 
				
			||||||
 | 
					        username -> Text,
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
		Reference in New Issue