added sqlx offline cache and switched to query_as!
This commit is contained in:
parent
e0369b50dd
commit
8f2cb6eda6
2
.env
2
.env
@ -1,2 +0,0 @@
|
|||||||
DATABASE_URL=sqlite:./sarmentine.db
|
|
||||||
SESSION_SECRET=gzC0+m1ol9sPHaZpEU/AwIQVA9STkmxrWK6HhCI7ovlNdVzQqR0sg8VHQCRxURQFmVNEiQvJ8cx7G7nNd3b4jw
|
|
||||||
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,2 +1,4 @@
|
|||||||
/target
|
/target
|
||||||
sarmentine.db*
|
sarmentine.db*
|
||||||
|
.env
|
||||||
|
.env.*
|
||||||
|
|||||||
62
.sqlx/query-59b62edeaea0297e51ae3d1d973f46cc1a0786ad5f86bf5f539d12f728136f1d.json
generated
Normal file
62
.sqlx/query-59b62edeaea0297e51ae3d1d973f46cc1a0786ad5f86bf5f539d12f728136f1d.json
generated
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
{
|
||||||
|
"db_name": "SQLite",
|
||||||
|
"query": "SELECT id AS \"id!\", username, email, password, bio, avatar_url, role, created_at\n FROM users WHERE email = ?",
|
||||||
|
"describe": {
|
||||||
|
"columns": [
|
||||||
|
{
|
||||||
|
"name": "id!",
|
||||||
|
"ordinal": 0,
|
||||||
|
"type_info": "Int64"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "username",
|
||||||
|
"ordinal": 1,
|
||||||
|
"type_info": "Text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "email",
|
||||||
|
"ordinal": 2,
|
||||||
|
"type_info": "Text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "password",
|
||||||
|
"ordinal": 3,
|
||||||
|
"type_info": "Text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "bio",
|
||||||
|
"ordinal": 4,
|
||||||
|
"type_info": "Text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "avatar_url",
|
||||||
|
"ordinal": 5,
|
||||||
|
"type_info": "Text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "role",
|
||||||
|
"ordinal": 6,
|
||||||
|
"type_info": "Text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "created_at",
|
||||||
|
"ordinal": 7,
|
||||||
|
"type_info": "Datetime"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"parameters": {
|
||||||
|
"Right": 1
|
||||||
|
},
|
||||||
|
"nullable": [
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
false
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"hash": "59b62edeaea0297e51ae3d1d973f46cc1a0786ad5f86bf5f539d12f728136f1d"
|
||||||
|
}
|
||||||
62
.sqlx/query-9496103101618f59b785c0c8d2cee4f6053055cb06db77dc8033c7e31d503a77.json
generated
Normal file
62
.sqlx/query-9496103101618f59b785c0c8d2cee4f6053055cb06db77dc8033c7e31d503a77.json
generated
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
{
|
||||||
|
"db_name": "SQLite",
|
||||||
|
"query": "SELECT id AS \"id!\", username, email, password, bio, avatar_url, role, created_at\n FROM users WHERE id = ?",
|
||||||
|
"describe": {
|
||||||
|
"columns": [
|
||||||
|
{
|
||||||
|
"name": "id!",
|
||||||
|
"ordinal": 0,
|
||||||
|
"type_info": "Int64"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "username",
|
||||||
|
"ordinal": 1,
|
||||||
|
"type_info": "Text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "email",
|
||||||
|
"ordinal": 2,
|
||||||
|
"type_info": "Text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "password",
|
||||||
|
"ordinal": 3,
|
||||||
|
"type_info": "Text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "bio",
|
||||||
|
"ordinal": 4,
|
||||||
|
"type_info": "Text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "avatar_url",
|
||||||
|
"ordinal": 5,
|
||||||
|
"type_info": "Text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "role",
|
||||||
|
"ordinal": 6,
|
||||||
|
"type_info": "Text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "created_at",
|
||||||
|
"ordinal": 7,
|
||||||
|
"type_info": "Datetime"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"parameters": {
|
||||||
|
"Right": 1
|
||||||
|
},
|
||||||
|
"nullable": [
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
false
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"hash": "9496103101618f59b785c0c8d2cee4f6053055cb06db77dc8033c7e31d503a77"
|
||||||
|
}
|
||||||
62
.sqlx/query-d12d0743a4bbe18465adb69102e3f7dc70ac567c7610cc9aa6f9c6bd84be6a6b.json
generated
Normal file
62
.sqlx/query-d12d0743a4bbe18465adb69102e3f7dc70ac567c7610cc9aa6f9c6bd84be6a6b.json
generated
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
{
|
||||||
|
"db_name": "SQLite",
|
||||||
|
"query": "SELECT id AS \"id!\", username, email, password, bio, avatar_url, role, created_at\n FROM users WHERE username = ?",
|
||||||
|
"describe": {
|
||||||
|
"columns": [
|
||||||
|
{
|
||||||
|
"name": "id!",
|
||||||
|
"ordinal": 0,
|
||||||
|
"type_info": "Int64"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "username",
|
||||||
|
"ordinal": 1,
|
||||||
|
"type_info": "Text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "email",
|
||||||
|
"ordinal": 2,
|
||||||
|
"type_info": "Text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "password",
|
||||||
|
"ordinal": 3,
|
||||||
|
"type_info": "Text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "bio",
|
||||||
|
"ordinal": 4,
|
||||||
|
"type_info": "Text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "avatar_url",
|
||||||
|
"ordinal": 5,
|
||||||
|
"type_info": "Text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "role",
|
||||||
|
"ordinal": 6,
|
||||||
|
"type_info": "Text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "created_at",
|
||||||
|
"ordinal": 7,
|
||||||
|
"type_info": "Datetime"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"parameters": {
|
||||||
|
"Right": 1
|
||||||
|
},
|
||||||
|
"nullable": [
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
false
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"hash": "d12d0743a4bbe18465adb69102e3f7dc70ac567c7610cc9aa6f9c6bd84be6a6b"
|
||||||
|
}
|
||||||
1475
Cargo.lock
generated
1475
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -19,3 +19,6 @@ serde = { version = "1", features = ["derive"] }
|
|||||||
chrono = { version = "0.4", features = ["serde"] }
|
chrono = { version = "0.4", features = ["serde"] }
|
||||||
# Error handling
|
# Error handling
|
||||||
anyhow = "1"
|
anyhow = "1"
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
cargo-generate-rpm = "0.20"
|
||||||
|
|||||||
@ -51,7 +51,7 @@ async fn index(
|
|||||||
async fn main() {
|
async fn main() {
|
||||||
dotenvy::dotenv().ok();
|
dotenvy::dotenv().ok();
|
||||||
|
|
||||||
let database_url = std::env::var("DATABASE_URL")
|
let database_url = std::env::var("SARMENTINE_DATABASE_URL")
|
||||||
.unwrap_or_else(|_| "sqlite:./sarmentine.db".into());
|
.unwrap_or_else(|_| "sqlite:./sarmentine.db".into());
|
||||||
|
|
||||||
let pool: SqlitePool = db::connect(&database_url).await;
|
let pool: SqlitePool = db::connect(&database_url).await;
|
||||||
@ -59,7 +59,7 @@ async fn main() {
|
|||||||
let session_store = SqliteStore::new(pool.clone());
|
let session_store = SqliteStore::new(pool.clone());
|
||||||
session_store.migrate().await.expect("session store migration failed");
|
session_store.migrate().await.expect("session store migration failed");
|
||||||
|
|
||||||
let session_secret = std::env::var("SESSION_SECRET")
|
let session_secret = std::env::var("SARMENTINE_SESSION_SECRET")
|
||||||
.unwrap_or_else(|_| "change-me-in-production-use-a-long-random-string!!".into());
|
.unwrap_or_else(|_| "change-me-in-production-use-a-long-random-string!!".into());
|
||||||
|
|
||||||
let session_layer = SessionManagerLayer::new(session_store)
|
let session_layer = SessionManagerLayer::new(session_store)
|
||||||
@ -69,6 +69,9 @@ async fn main() {
|
|||||||
session_secret.as_bytes(),
|
session_secret.as_bytes(),
|
||||||
));
|
));
|
||||||
|
|
||||||
|
let static_dir = std::env::var("SARMENTINE_STATIC_DIR")
|
||||||
|
.unwrap_or_else(|_| "static".into());
|
||||||
|
|
||||||
let app = Router::new()
|
let app = Router::new()
|
||||||
.route("/", get(index))
|
.route("/", get(index))
|
||||||
.route("/auth/register", get(register_page))
|
.route("/auth/register", get(register_page))
|
||||||
@ -76,7 +79,7 @@ async fn main() {
|
|||||||
.route("/auth/login", get(login_page))
|
.route("/auth/login", get(login_page))
|
||||||
.route("/auth/login", post(login_submit))
|
.route("/auth/login", post(login_submit))
|
||||||
.route("/auth/logout", post(logout))
|
.route("/auth/logout", post(logout))
|
||||||
.nest_service("/static", ServeDir::new("static"))
|
.nest_service("/static", ServeDir::new(&static_dir))
|
||||||
.layer(session_layer)
|
.layer(session_layer)
|
||||||
.with_state(pool);
|
.with_state(pool);
|
||||||
|
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
use chrono::NaiveDateTime;
|
use chrono::NaiveDateTime;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use sqlx::{FromRow, SqlitePool};
|
use sqlx::SqlitePool;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize, FromRow)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub struct User {
|
pub struct User {
|
||||||
pub id: i64,
|
pub id: i64,
|
||||||
pub username: String,
|
pub username: String,
|
||||||
@ -17,31 +17,34 @@ pub struct User {
|
|||||||
|
|
||||||
impl User {
|
impl User {
|
||||||
pub async fn find_by_id(pool: &SqlitePool, id: i64) -> sqlx::Result<Option<User>> {
|
pub async fn find_by_id(pool: &SqlitePool, id: i64) -> sqlx::Result<Option<User>> {
|
||||||
sqlx::query_as(
|
sqlx::query_as!(
|
||||||
"SELECT id, username, email, password, bio, avatar_url, role, created_at
|
User,
|
||||||
FROM users WHERE id = ?"
|
r#"SELECT id AS "id!", username, email, password, bio, avatar_url, role, created_at
|
||||||
|
FROM users WHERE id = ?"#,
|
||||||
|
id
|
||||||
)
|
)
|
||||||
.bind(id)
|
|
||||||
.fetch_optional(pool)
|
.fetch_optional(pool)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn find_by_username(pool: &SqlitePool, username: &str) -> sqlx::Result<Option<User>> {
|
pub async fn find_by_username(pool: &SqlitePool, username: &str) -> sqlx::Result<Option<User>> {
|
||||||
sqlx::query_as(
|
sqlx::query_as!(
|
||||||
"SELECT id, username, email, password, bio, avatar_url, role, created_at
|
User,
|
||||||
FROM users WHERE username = ?"
|
r#"SELECT id AS "id!", username, email, password, bio, avatar_url, role, created_at
|
||||||
|
FROM users WHERE username = ?"#,
|
||||||
|
username
|
||||||
)
|
)
|
||||||
.bind(username)
|
|
||||||
.fetch_optional(pool)
|
.fetch_optional(pool)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn find_by_email(pool: &SqlitePool, email: &str) -> sqlx::Result<Option<User>> {
|
pub async fn find_by_email(pool: &SqlitePool, email: &str) -> sqlx::Result<Option<User>> {
|
||||||
sqlx::query_as(
|
sqlx::query_as!(
|
||||||
"SELECT id, username, email, password, bio, avatar_url, role, created_at
|
User,
|
||||||
FROM users WHERE email = ?"
|
r#"SELECT id AS "id!", username, email, password, bio, avatar_url, role, created_at
|
||||||
|
FROM users WHERE email = ?"#,
|
||||||
|
email
|
||||||
)
|
)
|
||||||
.bind(email)
|
|
||||||
.fetch_optional(pool)
|
.fetch_optional(pool)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user