1
0
Fork 0

Add diesel and example page

This commit is contained in:
Florian RICHER (MrDev023) 2022-03-21 22:37:03 +01:00
parent 1197fe687b
commit d20ca7cfa9
20 changed files with 453 additions and 14 deletions

View file

@ -1,5 +1,4 @@
use actix_web::{get, Responder, web, HttpResponse};
use actix_web::{get, web, HttpResponse, Responder};
use yew::ServerRenderer;
use crate::views::components::hello::{Hello, HelloProps};
@ -7,8 +6,6 @@ use crate::views::components::hello::{Hello, HelloProps};
#[get("/{name}")]
async fn index(name: web::Path<String>) -> impl Responder {
let name = name.into_inner();
let renderer = ServerRenderer::<Hello>::with_props(HelloProps {
name
});
let renderer = ServerRenderer::<Hello>::with_props(HelloProps { name });
HttpResponse::Ok().body(renderer.render().await)
}
}

View file

@ -1 +1,2 @@
pub mod hello_controller;
pub mod hello_controller;
pub mod users_controller;

View file

@ -0,0 +1,44 @@
use actix_web::{get, web, Error, HttpResponse};
use yew::ServerRenderer;
use crate::{
models::user::{NewUser, User},
views::components::{
user::{UserComponent, UserComponentProps},
users::{UsersComponent, UsersComponentProps}
},
DbPool,
};
#[get("")]
async fn index(pool: web::Data<DbPool>) -> Result<HttpResponse, Error> {
let users = web::block(move || {
let conn = pool.get()?;
User::all(&conn)
})
.await?
.map_err(actix_web::error::ErrorInternalServerError)?;
let renderer =
ServerRenderer::<UsersComponent>::with_props(UsersComponentProps { users: users.clone() });
Ok(HttpResponse::Ok().body(renderer.render().await))
}
#[get("")]
async fn create(pool: web::Data<DbPool>) -> Result<HttpResponse, Error> {
let user = User::new(NewUser {
name: "John".to_string(),
});
let u = user.clone();
web::block(move || {
let conn = pool.get()?;
u.insert(&conn)
})
.await?
.map_err(actix_web::error::ErrorInternalServerError)?;
let renderer =
ServerRenderer::<UserComponent>::with_props(UserComponentProps { user: user.clone() });
Ok(HttpResponse::Ok().body(renderer.render().await))
}

View file

@ -1,12 +1,38 @@
#[macro_use]
extern crate diesel; // Required for schema.rs
pub(self) mod controllers;
pub(self) mod models;
pub(self) mod schema;
pub(self) mod views;
use actix_web::{App, HttpServer, web};
pub(self) type DbPool = r2d2::Pool<ConnectionManager<SqliteConnection>>;
use actix_web::{middleware, web, App, HttpServer};
use diesel::{
r2d2::{self, ConnectionManager},
SqliteConnection,
};
#[actix_web::main]
async fn main() -> std::io::Result<()>{
HttpServer::new(|| {
App::new().service(web::scope("/hello").service(controllers::hello_controller::index))
async fn main() -> std::io::Result<()> {
dotenv::dotenv().ok();
env_logger::init_from_env(env_logger::Env::new().default_filter_or("info"));
// set up database connection pool
let conn_spec = std::env::var("DATABASE_URL").expect("DATABASE_URL");
let manager = ConnectionManager::<SqliteConnection>::new(conn_spec);
let pool = r2d2::Pool::builder()
.build(manager)
.expect("Failed to create pool.");
HttpServer::new(move || {
App::new()
.app_data(web::Data::new(pool.clone()))
.wrap(middleware::Logger::default())
.service(web::scope("/hello").service(controllers::hello_controller::index))
.service(web::scope("/users").service(controllers::users_controller::index))
.service(web::scope("/user").service(controllers::users_controller::create))
})
.bind(("127.0.0.1", 8000))?
.run()

3
src/models/mod.rs Normal file
View file

@ -0,0 +1,3 @@
pub(self) type DbError = Box<dyn std::error::Error + Send + Sync>;
pub mod user;

64
src/models/user.rs Normal file
View file

@ -0,0 +1,64 @@
use diesel::prelude::*;
use serde::{Deserialize, Serialize};
use uuid::Uuid;
use crate::schema::users;
use super::DbError;
#[derive(Debug, Clone, Serialize, Deserialize, Queryable, Insertable, AsChangeset, PartialEq)]
pub struct User {
pub id: String,
pub name: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct NewUser {
pub name: String,
}
impl User {
pub fn new(new_user: NewUser) -> Self {
Self {
id: Uuid::new_v4().to_string(),
name: new_user.name,
}
}
pub fn all(conn: &SqliteConnection) -> Result<Vec<Self>, DbError> {
users::table.load::<Self>(conn).map_err(Into::into)
}
pub fn find_by_id(conn: &SqliteConnection, id: String) -> Result<Self, DbError> {
users::table
.filter(users::id.eq(id))
.first::<Self>(conn)
.map_err(Into::into)
}
pub fn insert(&self, conn: &SqliteConnection) -> Result<(), DbError> {
use crate::schema::users::dsl::*;
diesel::insert_into(users).values(self).execute(conn)?;
Ok(())
}
pub fn update(&self, conn: &SqliteConnection) -> Result<(), DbError> {
use crate::schema::users::dsl::*;
diesel::update(users.find(self.id.clone()))
.set(self)
.execute(conn)?;
Ok(())
}
pub fn delete(&self, conn: &SqliteConnection) -> Result<(), DbError> {
use crate::schema::users::dsl::*;
diesel::delete(users.filter(id.eq(self.id.clone()))).execute(conn)?;
Ok(())
}
}

6
src/schema.rs Normal file
View file

@ -0,0 +1,6 @@
table! {
users (id) {
id -> Text,
name -> Text,
}
}

View file

@ -1 +1,3 @@
pub mod hello;
pub mod hello;
pub mod user;
pub mod users;

View file

@ -0,0 +1,18 @@
use yew::prelude::*;
use crate::models::user::User;
#[derive(Properties, PartialEq)]
pub struct UserComponentProps {
pub user: User,
}
#[function_component]
pub fn UserComponent(props: &UserComponentProps) -> Html {
html! {
<div>
<p>{ props.user.clone().id } </p>
<p>{ props.user.clone().name } </p>
</div>
}
}

View file

@ -0,0 +1,21 @@
use yew::prelude::*;
use crate::models::user::User;
use crate::views::components::user::UserComponent;
#[derive(Properties, PartialEq)]
pub struct UsersComponentProps {
pub users: Vec<User>,
}
#[function_component]
pub fn UsersComponent(props: &UsersComponentProps) -> Html {
let users = props.users.clone().iter().map(|user| html! {
<UserComponent user={user.clone()} />
}).collect::<Html>();
html! {
<div>
{ users }
</div>
}
}