feat: got sqlx working with axum and leptos

This commit is contained in:
Andrew Rioux 2025-01-24 15:31:10 -05:00
parent 8695685eb3
commit 814125d462
Signed by: andrew.rioux
GPG Key ID: 9B8BAC47C17ABB94
7 changed files with 72 additions and 10 deletions

1
Cargo.lock generated
View File

@ -2810,6 +2810,7 @@ dependencies = [
"leptos_router",
"pbkdf2",
"rpassword",
"serde",
"sha2",
"sqlx",
"structopt",

View File

@ -36,6 +36,7 @@ rpassword = { version = "7.3", optional = true }
pbkdf2 = { version = "0.12", features = ["simple", "sha2"], optional = true }
sha2 = { version = "0.10", optional = true }
hex = { version = "0.4", optional = true }
serde = "1.0"
[features]
hydrate = ["leptos/hydrate"]

View File

@ -63,8 +63,6 @@ pub fn App() -> impl IntoView {
/// Renders the home page of your application.
#[component]
fn HomePage() -> impl IntoView {
use web_sys::WebSocket;
use std::sync::Arc;
use leptos_use::{UseWebSocketReturn, use_websocket};
// Creates a reactive value to update the button

View File

@ -19,9 +19,6 @@ where
let salt_string = hex::encode(salt.as_str().as_bytes());
let password_string = hex::encode(&key[..]);
tracing::debug!("New password hash: {password_string}");
tracing::debug!("New password salt: {salt_string}");
sqlx::query!(
"UPDATE users SET password_hash = ?, password_salt = ? WHERE user_id = ?",
password_string,

View File

@ -2,6 +2,8 @@ pub mod app;
pub mod users;
pub mod db;
#[cfg(feature = "hydrate")]
#[wasm_bindgen::prelude::wasm_bindgen]
pub fn hydrate() {

View File

@ -1,8 +1,67 @@
use leptos::prelude::*;
use serde::{Serialize, Deserialize};
#[cfg(feature = "ssr")]
use {
sqlx::SqlitePool
};
#[derive(Clone, Serialize, Deserialize)]
pub struct PubUser {
user_id: i64,
user_name: String
}
#[server]
async fn list_users() -> Result<Vec<PubUser>, ServerFnError> {
use leptos::server_fn::error::NoCustomError;
let pool = expect_context::<SqlitePool>();
let users = sqlx::query_as!(
PubUser,
"SELECT user_id, user_name FROM users"
)
.fetch_all(&pool)
.await?;
Ok(users)
}
#[component]
pub fn UserView() -> impl IntoView {
let user_list = Resource::new(|| (), |_| async move { list_users().await });
view! {
<p>"User view"</p>
<h1>"User list"</h1>
<Suspense
fallback=move || view! { <p>"Loading..."</p> }
>
<ErrorBoundary
fallback=|errors| view! {
<p>"Errors loading users!"</p>
<ul>
{move || errors.get()
.into_iter()
.map(|(_, e)| view! { <li>{e.to_string()}</li> })
.collect::<Vec<_>>()}
</ul>
}
>
{move || Suspend::new(async move {
let users_res = user_list.await;
users_res.map(|users| view! {
<ul>
{users
.into_iter()
.map(|user| view! {
<li>{user.user_id}": "{user.user_name}</li>
})
.collect::<Vec<_>>()}
</ul>
})
})}
</ErrorBoundary>
</Suspense>
}
}

View File

@ -51,7 +51,11 @@ pub async fn serve_web(options: crate::cli::Options, db: SqlitePool) -> anyhow::
let app = Router::new()
.route("/ws", axum::routing::any(websocket))
.leptos_routes(&leptos_options, routes, {
.leptos_routes_with_context(
&leptos_options,
routes,
move || provide_context(db.clone()),
{
let leptos_options = leptos_options.clone();
move || shell(leptos_options.clone())
})