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