Skip to content

Commit f7f319b

Browse files
committed
Copy en files to zh
Signed-off-by: Michael Yuan <michael@secondstate.io>
1 parent 1b22873 commit f7f319b

File tree

7 files changed

+650
-145
lines changed

7 files changed

+650
-145
lines changed

i18n/zh/docusaurus-plugin-content-docs/current/develop/rust/database/my_sql_driver.md

Lines changed: 186 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ The database connection is necessary for today's enterprise development. WasmEdg
88

99
<!-- prettier-ignore -->
1010
:::note
11-
Before we start, ensure [you have Rust and WasmEdge installed](../setup.md). If you are connecting to a remote MySQL database using TLS, you will need to [install the TLS plugin](../../../start/install.md#tls-plug-in) for WasmEdge as well.
11+
Before we start, [you need to have Rust and WasmEdge installed](../setup.md).
12+
Make sure that you read the [special notes on networking apps](../setup#special-notes) especially if you are compiling Rust programs on a Mac.
1213
:::
1314

1415
## Run the example
@@ -20,28 +21,201 @@ git clone https://github.com/WasmEdge/wasmedge-db-examples
2021
cd wasmedge-db-examples/mysql_async
2122

2223
# Compile the rust code into WASM
23-
cargo build --target wasm32-wasi --release
24+
RUSTFLAGS="--cfg wasmedge --cfg tokio_unstable" cargo build --target wasm32-wasi --release
2425

2526
# Execute MySQL statements against a MySQL database at mysql://user:passwd@127.0.0.1:3306
2627
wasmedge --env "DATABASE_URL=mysql://user:passwd@127.0.0.1:3306/mysql" target/wasm32-wasi/release/crud.wasm
2728
```
2829

29-
To use TLS, you will need to turn on the `default-rustls` feature in `Cargo.toml`.
30-
31-
```toml
32-
mysql_async_wasi = { version = "0.31", features = [ "default-rustls" ] }
33-
```
30+
<!-- prettier-ignore -->
31+
:::note
32+
Since we have TLS enabled by default in this example, you will need the [wasi-sdk version of clang](../setup#tls-on-macos) for compiling it on MacOS.
33+
:::
3434

35+
To use TLS, you will need to turn on the `default-rustls` feature on the `mysql_async` crate in `Cargo.toml`.
3536
Then, run the application as follows.
3637

3738
```toml
3839
# Execute MySQL statements against an AWS RDS database that requires TLS
3940
wasmedge --env "DATABASE_SSL=1" --env "DATABASE_URL=mysql://user:passwd@mydb.123456789012.us-east-1.rds.amazonaws.com:3306/mysql" crud.wasm
4041
```
4142

42-
## Code explanation
43+
## Configuration
44+
45+
In order to compile the `mysql_async` and `tokio` crates, we will need to apply two patches to add
46+
WasmEdge-specific socket APIs to those crates. The following example shows that the TLS connection is enabled.
47+
48+
```
49+
[patch.crates-io]
50+
tokio = { git = "https://github.com/second-state/wasi_tokio.git", branch = "v1.36.x" }
51+
socket2 = { git = "https://github.com/second-state/socket2.git", branch = "v0.5.x" }
52+
53+
[dependencies]
54+
mysql_async = { version = "0.34", default-features=false, features = [ "default-rustls" ], git="https://github.com/blackbeam/mysql_async.git" }
55+
zstd-sys = "=2.0.9"
56+
tokio = { version = "1", features = [ "io-util", "fs", "net", "time", "rt", "macros"] }
57+
```
58+
59+
## Code example
60+
61+
The following code shows how to connect to a MySQL database server, and then insert, update, and delete records using SQL
62+
statements.
63+
64+
Connect to a MySQL database.
65+
66+
```
67+
// Below we create a customized connection pool
68+
let opts = Opts::from_url(&*get_url()).unwrap();
69+
let mut builder = OptsBuilder::from_opts(opts);
70+
if std::env::var("DATABASE_SSL").is_ok() {
71+
builder = builder.ssl_opts(SslOpts::default());
72+
}
73+
// The connection pool will have a min of 5 and max of 10 connections.
74+
let constraints = PoolConstraints::new(5, 10).unwrap();
75+
let pool_opts = PoolOpts::default().with_constraints(constraints);
76+
77+
let pool = Pool::new(builder.pool_opts(pool_opts));
78+
let mut conn = pool.get_conn().await.unwrap();
79+
```
80+
81+
Create a table on the connected database.
82+
83+
```
84+
// create table if no tables exist
85+
let result = r"SHOW TABLES LIKE 'orders';"
86+
.with(())
87+
.map(&mut conn, |s: String| String::from(s))
88+
.await?;
89+
90+
if result.len() == 0 {
91+
// table doesn't exist, create a new one
92+
r"CREATE TABLE orders (order_id INT, production_id INT, quantity INT, amount FLOAT, shipping FLOAT, tax FLOAT, shipping_address VARCHAR(20));".ignore(&mut conn).await?;
93+
println!("create new table");
94+
} else {
95+
// delete all data from the table.
96+
println!("delete all from orders");
97+
r"DELETE FROM orders;".ignore(&mut conn).await?;
98+
}
99+
```
100+
101+
Insert some records into the MySQL database using SQL.
102+
103+
```
104+
let orders = vec![
105+
Order::new(1, 12, 2, 56.0, 15.0, 2.0, String::from("Mataderos 2312")),
106+
Order::new(2, 15, 3, 256.0, 30.0, 16.0, String::from("1234 NW Bobcat")),
107+
Order::new(3, 11, 5, 536.0, 50.0, 24.0, String::from("20 Havelock")),
108+
Order::new(4, 8, 8, 126.0, 20.0, 12.0, String::from("224 Pandan Loop")),
109+
Order::new(5, 24, 1, 46.0, 10.0, 2.0, String::from("No.10 Jalan Besar")),
110+
];
111+
112+
r"INSERT INTO orders (order_id, production_id, quantity, amount, shipping, tax, shipping_address)
113+
VALUES (:order_id, :production_id, :quantity, :amount, :shipping, :tax, :shipping_address)"
114+
.with(orders.iter().map(|order| {
115+
params! {
116+
"order_id" => order.order_id,
117+
"production_id" => order.production_id,
118+
"quantity" => order.quantity,
119+
"amount" => order.amount,
120+
"shipping" => order.shipping,
121+
"tax" => order.tax,
122+
"shipping_address" => &order.shipping_address,
123+
}
124+
}))
125+
.batch(&mut conn)
126+
.await?;
127+
```
128+
129+
Query the database.
130+
131+
```
132+
// query data
133+
let loaded_orders = "SELECT * FROM orders"
134+
.with(())
135+
.map(
136+
&mut conn,
137+
|(order_id, production_id, quantity, amount, shipping, tax, shipping_address)| {
138+
Order::new(
139+
order_id,
140+
production_id,
141+
quantity,
142+
amount,
143+
shipping,
144+
tax,
145+
shipping_address,
146+
)
147+
},
148+
)
149+
.await?;
150+
dbg!(loaded_orders.len());
151+
dbg!(loaded_orders);
152+
```
153+
154+
Delete some records from the database.
155+
156+
```
157+
// // delete some data
158+
r"DELETE FROM orders WHERE order_id=4;"
159+
.ignore(&mut conn)
160+
.await?;
161+
162+
// query data
163+
let loaded_orders = "SELECT * FROM orders"
164+
.with(())
165+
.map(
166+
&mut conn,
167+
|(order_id, production_id, quantity, amount, shipping, tax, shipping_address)| {
168+
Order::new(
169+
order_id,
170+
production_id,
171+
quantity,
172+
amount,
173+
shipping,
174+
tax,
175+
shipping_address,
176+
)
177+
},
178+
)
179+
.await?;
180+
dbg!(loaded_orders.len());
181+
dbg!(loaded_orders);
182+
```
183+
184+
Update records in the MySQL database.
185+
186+
```
187+
// // update some data
188+
r"UPDATE orders
189+
SET shipping_address = '8366 Elizabeth St.'
190+
WHERE order_id = 2;"
191+
.ignore(&mut conn)
192+
.await?;
193+
// query data
194+
let loaded_orders = "SELECT * FROM orders"
195+
.with(())
196+
.map(
197+
&mut conn,
198+
|(order_id, production_id, quantity, amount, shipping, tax, shipping_address)| {
199+
Order::new(
200+
order_id,
201+
production_id,
202+
quantity,
203+
amount,
204+
shipping,
205+
tax,
206+
shipping_address,
207+
)
208+
},
209+
)
210+
.await?;
211+
dbg!(loaded_orders.len());
212+
dbg!(loaded_orders);
213+
```
214+
215+
Close the database connection.
216+
217+
```
218+
drop(conn);
219+
pool.disconnect().await.unwrap();
220+
```
43221

44-
<!-- prettier-ignore -->
45-
:::info
46-
Work in Progress
47-
:::

i18n/zh/docusaurus-plugin-content-docs/current/develop/rust/database/postgres_driver.md

Lines changed: 126 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ A database connection is necessary for today's enterprise development. WasmEdge
88

99
<!-- prettier-ignore -->
1010
:::note
11-
Before we start, make sure [you have Rust and WasmEdge installed](../setup.md).
11+
Before we start, [you need to have Rust and WasmEdge installed](../setup.md).
12+
Make sure that you read the [special notes on networking apps](../setup#special-notes) especially if you are compiling Rust programs on a Mac.
1213
:::
1314

1415
## Run the example
@@ -20,15 +21,134 @@ git clone https://github.com/WasmEdge/wasmedge-db-examples
2021
cd wasmedge-db-examples/postgres
2122

2223
# Compile the rust code into WASM
23-
cargo build --target wasm32-wasi --release
24+
RUSTFLAGS="--cfg wasmedge --cfg tokio_unstable" cargo build --target wasm32-wasi --release
2425

2526
# Execute SQL statements against a PostgreSQL database at postgres://user:passwd@localhost/testdb
2627
wasmedge --env "DATABASE_URL=postgres://user:passwd@localhost/testdb" target/wasm32-wasi/release/crud.wasm
2728
```
2829

30+
## Configuration
31+
32+
In order to compile the `tokio-postgres` and `tokio` crates, we will need to apply patches to add WasmEdge-specific socket APIs to those crates in `Cargo.toml`.
33+
34+
```
35+
[patch.crates-io]
36+
tokio = { git = "https://github.com/second-state/wasi_tokio.git", branch = "v1.36.x" }
37+
socket2 = { git = "https://github.com/second-state/socket2.git", branch = "v0.5.x" }
38+
tokio-postgres = { git = "https://github.com/second-state/rust-postgres.git" }
39+
40+
[dependencies]
41+
tokio-postgres = "0.7"
42+
tokio = { version = "1", features = [
43+
"io-util",
44+
"fs",
45+
"net",
46+
"time",
47+
"rt",
48+
"macros",
49+
] }
50+
```
51+
2952
## Code explanation
3053

31-
<!-- prettier-ignore -->
32-
:::info
33-
Work in Progress
34-
:::
54+
We first use a Rust struct to represent the database table.
55+
56+
```rust
57+
#[derive(Debug)]
58+
struct Order {
59+
order_id: i32,
60+
production_id: i32,
61+
quantity: i32,
62+
amount: f32,
63+
shipping: f32,
64+
tax: f32,
65+
shipping_address: String,
66+
}
67+
68+
impl Order {
69+
fn new(
70+
order_id: i32,
71+
production_id: i32,
72+
quantity: i32,
73+
amount: f32,
74+
shipping: f32,
75+
tax: f32,
76+
shipping_address: String,
77+
) -> Self {
78+
Self {
79+
order_id,
80+
production_id,
81+
quantity,
82+
amount,
83+
shipping,
84+
tax,
85+
shipping_address,
86+
}
87+
}
88+
}
89+
```
90+
91+
Then, you can use the `tokio-postgres` API to access the database through its connection URL.
92+
The code below shows how to perform basic CRUD operations using SQL commands.
93+
94+
```rust
95+
#[tokio::main(flavor = "current_thread")]
96+
async fn main() -> Result<(), Error> {
97+
// Connect to the database.
98+
let (client, connection) = tokio_postgres::connect(&*get_url(), NoTls).await?;
99+
100+
// The connection object performs the actual communication with the database,
101+
// so spawn it off to run on its own.
102+
tokio::spawn(async move {
103+
if let Err(e) = connection.await {
104+
eprintln!("connection error: {}", e);
105+
}
106+
});
107+
108+
client.execute("CREATE TABLE IF NOT EXISTS orders (order_id INT, production_id INT, quantity INT, amount REAL, shipping REAL, tax REAL, shipping_address VARCHAR(256));", &[]).await?;
109+
110+
let orders = vec![
111+
Order::new(1, 12, 2, 56.0, 15.0, 2.0, String::from("Mataderos 2312")),
112+
Order::new(2, 15, 3, 256.0, 30.0, 16.0, String::from("1234 NW Bobcat")),
113+
Order::new(3, 11, 5, 536.0, 50.0, 24.0, String::from("20 Havelock")),
114+
Order::new(4, 8, 8, 126.0, 20.0, 12.0, String::from("224 Pandan Loop")),
115+
Order::new(5, 24, 1, 46.0, 10.0, 2.0, String::from("No.10 Jalan Besar")),
116+
];
117+
118+
for order in orders.iter() {
119+
client.execute(
120+
"INSERT INTO orders (order_id, production_id, quantity, amount, shipping, tax, shipping_address) VALUES ($1, $2, $3, $4, $5, $6, $7)",
121+
&[&order.order_id, &order.production_id, &order.quantity, &order.amount, &order.shipping, &order.tax, &order.shipping_address]
122+
).await?;
123+
}
124+
125+
let rows = client.query("SELECT * FROM orders;", &[]).await?;
126+
for row in rows.iter() {
127+
let order_id : i32 = row.get(0);
128+
println!("order_id {}", order_id);
129+
130+
let production_id : i32 = row.get(1);
131+
println!("production_id {}", production_id);
132+
133+
let quantity : i32 = row.get(2);
134+
println!("quantity {}", quantity);
135+
136+
let amount : f32 = row.get(3);
137+
println!("amount {}", amount);
138+
139+
let shipping : f32 = row.get(4);
140+
println!("shipping {}", shipping);
141+
142+
let tax : f32 = row.get(5);
143+
println!("tax {}", tax);
144+
145+
let shipping_address : &str = row.get(6);
146+
println!("shipping_address {}", shipping_address);
147+
}
148+
149+
client.execute("DELETE FROM orders;", &[]).await?;
150+
151+
Ok(())
152+
}
153+
```
154+

0 commit comments

Comments
 (0)