sqlx, db setup, users migration
This commit is contained in:
parent
8461e542de
commit
e2a49963e5
1
.gitignore
vendored
1
.gitignore
vendored
@ -1 +1,2 @@
|
|||||||
/target
|
/target
|
||||||
|
sarmentine.db*
|
||||||
|
|||||||
1585
Cargo.lock
generated
1585
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -9,6 +9,7 @@ tokio = { version = "1", features = ["full"] }
|
|||||||
askama = { version = "0.12", features = ["with-axum"] }
|
askama = { version = "0.12", features = ["with-axum"] }
|
||||||
askama_axum = "0.4"
|
askama_axum = "0.4"
|
||||||
tower-http = { version = "0.5", features = ["fs"] }
|
tower-http = { version = "0.5", features = ["fs"] }
|
||||||
|
sqlx = { version = "0.7", features = ["runtime-tokio", "sqlite", "migrate"] }
|
||||||
|
dotenvy = "0.15"
|
||||||
# Error handling
|
# Error handling
|
||||||
anyhow = "1"
|
anyhow = "1"
|
||||||
|
|||||||
10
migrations/0001_users.sql
Normal file
10
migrations/0001_users.sql
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
CREATE TABLE IF NOT EXISTS users (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
username TEXT NOT NULL UNIQUE COLLATE NOCASE,
|
||||||
|
email TEXT NOT NULL UNIQUE COLLATE NOCASE,
|
||||||
|
password TEXT NOT NULL,
|
||||||
|
bio TEXT,
|
||||||
|
avatar_url TEXT,
|
||||||
|
role TEXT NOT NULL DEFAULT 'member' CHECK(role IN ('member', 'admin')),
|
||||||
|
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||||
|
);
|
||||||
29
src/db.rs
Normal file
29
src/db.rs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
use sqlx::{sqlite::SqlitePoolOptions, SqlitePool};
|
||||||
|
|
||||||
|
pub async fn connect(database_url: &str) -> SqlitePool {
|
||||||
|
let pool = SqlitePoolOptions::new()
|
||||||
|
.max_connections(5)
|
||||||
|
.connect(database_url)
|
||||||
|
.await
|
||||||
|
.expect("failed to connect to database");
|
||||||
|
|
||||||
|
sqlx::migrate!("./migrations")
|
||||||
|
.run(&pool)
|
||||||
|
.await
|
||||||
|
.expect("migrations failed");
|
||||||
|
|
||||||
|
// WAL mode: reads and writes can happen concurrently
|
||||||
|
sqlx::query("PRAGMA journal_mode=WAL;")
|
||||||
|
.execute(&pool)
|
||||||
|
.await
|
||||||
|
.expect("failed to set WAL mode");
|
||||||
|
|
||||||
|
// SQLite ignores foreign keys by default -- turn them on
|
||||||
|
sqlx::query("PRAGMA foreign_keys=ON;")
|
||||||
|
.execute(&pool)
|
||||||
|
.await
|
||||||
|
.expect("failed to enable foreign keys");
|
||||||
|
|
||||||
|
println!("database ready");
|
||||||
|
pool
|
||||||
|
}
|
||||||
17
src/main.rs
17
src/main.rs
@ -1,10 +1,11 @@
|
|||||||
|
mod db;
|
||||||
|
|
||||||
use askama::Template;
|
use askama::Template;
|
||||||
use askama_axum::IntoResponse;
|
use askama_axum::IntoResponse;
|
||||||
use axum::{routing::get, Router};
|
use axum::{routing::get, Router};
|
||||||
|
use sqlx::SqlitePool;
|
||||||
use tower_http::services::ServeDir;
|
use tower_http::services::ServeDir;
|
||||||
|
|
||||||
// Represents the currently logged-in user, passed into every template.
|
|
||||||
// None = logged out.
|
|
||||||
pub struct CurrentUser {
|
pub struct CurrentUser {
|
||||||
pub username: String,
|
pub username: String,
|
||||||
}
|
}
|
||||||
@ -19,15 +20,23 @@ struct IndexTemplate {
|
|||||||
async fn index() -> impl IntoResponse {
|
async fn index() -> impl IntoResponse {
|
||||||
IndexTemplate {
|
IndexTemplate {
|
||||||
title: "home".into(),
|
title: "home".into(),
|
||||||
current_user: None, // no auth yet
|
current_user: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() {
|
async fn main() {
|
||||||
|
dotenvy::dotenv().ok();
|
||||||
|
|
||||||
|
let database_url = std::env::var("DATABASE_URL")
|
||||||
|
.unwrap_or_else(|_| "sqlite:./sarmentine.db".into());
|
||||||
|
|
||||||
|
let pool: SqlitePool = db::connect(&database_url).await;
|
||||||
|
|
||||||
let app = Router::new()
|
let app = Router::new()
|
||||||
.route("/", get(index))
|
.route("/", get(index))
|
||||||
.nest_service("/static", ServeDir::new("static"));
|
.nest_service("/static", ServeDir::new("static"))
|
||||||
|
.with_state(pool);
|
||||||
|
|
||||||
let listener = tokio::net::TcpListener::bind("127.0.0.1:3000")
|
let listener = tokio::net::TcpListener::bind("127.0.0.1:3000")
|
||||||
.await
|
.await
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user