參考資訊:
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
