參考資訊:
https://www.rust-lang.org/learn/get-started
https://www.readfog.com/a/1674123278515539968
http://bzz.wallizard.com:8081/share/books/RUST/Programming%20Rust%202nd%20Edition.pdf
產生樣板
$ cargo new hello $ cd hello
Cargo.toml
[package] name = "hello" version = "0.1.0" edition = "2021" [dependencies] axum = "0" anyhow = "1.0" futures = "0.3" actix-web = "1.0.8" serde = { version = "1.0", features = [ "derive" ] } tokio = { version = "1.12.0", features = [ "full" ] } sqlx = { version = "0.5.7", features = [ "runtime-tokio-rustls", "sqlite" ] }
src/main.rs
use std::net::SocketAddr; use sqlx::sqlite::SqlitePool; use axum::extract::Extension; use axum::{response::Html, routing::get, Router}; #[tokio::main] async fn main() { let _pool = SqlitePool::connect("sqlite:test.db").await.expect("failed to connect sqlite"); let app = Router::new() .route("/", get(get_index)) .route("/create", axum::routing::post(post_create)) .route("/read", axum::routing::post(post_read)) .route("/update", axum::routing::post(post_update)) .route("/delete", axum::routing::post(post_delete)) .layer(Extension(_pool)); let addr = SocketAddr::from(([127, 0, 0, 1], 3000)); axum::Server::bind(&addr) .serve(app.into_make_service()) .await .unwrap(); } async fn get_index(Extension(_pool): Extension<SqlitePool>) -> Html<String> { Html(format!(" <title>CRUD Test</title> <form action = \"/create\" method = \"post\"><button type = \"submit\">create</button></form> <form action = \"/read\" method = \"post\"><button type = \"submit\">read</button></form> <form action = \"/update\" method = \"post\"><button type = \"submit\">update</button></form> <form action = \"/delete\" method = \"post\"><button type = \"submit\">delete</button></form>")) } async fn post_create(Extension(_pool): Extension<SqlitePool>) -> Html<String> { let user : &str = "test"; let pass : &str = "1234"; let _r = sqlx::query!("create table if not exists account(name text primary key, password text not null)").fetch_all(&_pool).await; let _r = sqlx::query!(r#"insert into account(name, password) values($1, $2)"#, user, pass).fetch_all(&_pool).await; Html(format!("complete !").to_string()) } async fn post_read(Extension(_pool): Extension<SqlitePool>) -> Html<String> { let _r = sqlx::query!("select * from account").fetch_all(&_pool).await; Html(format!("{:?}", _r).to_string()) } async fn post_update(Extension(_pool): Extension<SqlitePool>) -> Html<String> { let user : &str = "test"; let pass : &str = "5678"; let _r = sqlx::query!(r#"update account set password=$2 where name=$1"#, user, pass).fetch_all(&_pool).await; Html(format!("complete !").to_string()) } async fn post_delete(Extension(_pool): Extension<SqlitePool>) -> Html<String> { let _r = sqlx::query!("drop table account").fetch_all(&_pool).await; Html(format!("complete !").to_string()) }
產生資料庫
$ export DATABASE_URL="sqlite:test.db" $ sqlx migrate add test $ vim migrations/xxx_test.sql -- Add migration script here CREATE TABLE account ( name TEXT PRIMARY KEY, password TEXT NOT NULL ); $ sqlx db create $ sqlx migrate run
執行
$ cargo run
開啟網頁並且輸入http://127.0.0.1:3000