Skip to content

Commit 08110ac

Browse files
authored
Merge pull request #329 from blackbeam/22.2.0-release
22.2.0 release
2 parents 3d363c2 + 3751d7f commit 08110ac

File tree

4 files changed

+151
-119
lines changed

4 files changed

+151
-119
lines changed

Cargo.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "mysql"
3-
version = "22.1.0"
3+
version = "22.2.0"
44
authors = ["blackbeam"]
55
description = "Mysql client library implemented in rust"
66
license = "MIT/Apache-2.0"
@@ -50,6 +50,7 @@ lazy_static = "1.4.0"
5050
rand = "0.8.2"
5151
serde_derive = "1"
5252
time = "0.3"
53+
frunk = "0.4"
5354

5455
[dependencies]
5556
bufstream = "~0.1"
@@ -78,7 +79,7 @@ features = ["dangerous_configuration"]
7879
optional = true
7980

8081
[dependencies.rustls-pemfile]
81-
version = "0.2.1"
82+
version = "1.0.0"
8283
optional = true
8384

8485
[dependencies.webpki]

README.md

Lines changed: 61 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -50,53 +50,59 @@ struct Payment {
5050
account_name: Option<String>,
5151
}
5252

53-
let url = "mysql://root:password@localhost:3307/db_name";
5453

55-
let pool = Pool::new(url)?;
56-
57-
let mut conn = pool.get_conn()?;
58-
59-
// Let's create a table for payments.
60-
conn.query_drop(
61-
r"CREATE TEMPORARY TABLE payment (
62-
customer_id int not null,
63-
amount int not null,
64-
account_name text
65-
)")?;
66-
67-
let payments = vec![
68-
Payment { customer_id: 1, amount: 2, account_name: None },
69-
Payment { customer_id: 3, amount: 4, account_name: Some("foo".into()) },
70-
Payment { customer_id: 5, amount: 6, account_name: None },
71-
Payment { customer_id: 7, amount: 8, account_name: None },
72-
Payment { customer_id: 9, amount: 10, account_name: Some("bar".into()) },
73-
];
74-
75-
// Now let's insert payments to the database
76-
conn.exec_batch(
77-
r"INSERT INTO payment (customer_id, amount, account_name)
78-
VALUES (:customer_id, :amount, :account_name)",
79-
payments.iter().map(|p| params! {
80-
"customer_id" => p.customer_id,
81-
"amount" => p.amount,
82-
"account_name" => &p.account_name,
83-
})
84-
)?;
85-
86-
// Let's select payments from database. Type inference should do the trick here.
87-
let selected_payments = conn
88-
.query_map(
89-
"SELECT customer_id, amount, account_name from payment",
90-
|(customer_id, amount, account_name)| {
91-
Payment { customer_id, amount, account_name }
92-
},
54+
fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
55+
let url = "mysql://root:password@localhost:3307/db_name";
56+
# Opts::try_from(url)?;
57+
# let url = get_opts();
58+
let pool = Pool::new(url)?;
59+
60+
let mut conn = pool.get_conn()?;
61+
62+
// Let's create a table for payments.
63+
conn.query_drop(
64+
r"CREATE TEMPORARY TABLE payment (
65+
customer_id int not null,
66+
amount int not null,
67+
account_name text
68+
)")?;
69+
70+
let payments = vec![
71+
Payment { customer_id: 1, amount: 2, account_name: None },
72+
Payment { customer_id: 3, amount: 4, account_name: Some("foo".into()) },
73+
Payment { customer_id: 5, amount: 6, account_name: None },
74+
Payment { customer_id: 7, amount: 8, account_name: None },
75+
Payment { customer_id: 9, amount: 10, account_name: Some("bar".into()) },
76+
];
77+
78+
// Now let's insert payments to the database
79+
conn.exec_batch(
80+
r"INSERT INTO payment (customer_id, amount, account_name)
81+
VALUES (:customer_id, :amount, :account_name)",
82+
payments.iter().map(|p| params! {
83+
"customer_id" => p.customer_id,
84+
"amount" => p.amount,
85+
"account_name" => &p.account_name,
86+
})
9387
)?;
9488

95-
// Let's make sure, that `payments` equals to `selected_payments`.
96-
// Mysql gives no guaranties on order of returned rows
97-
// without `ORDER BY`, so assume we are lucky.
98-
assert_eq!(payments, selected_payments);
99-
println!("Yay!");
89+
// Let's select payments from database. Type inference should do the trick here.
90+
let selected_payments = conn
91+
.query_map(
92+
"SELECT customer_id, amount, account_name from payment",
93+
|(customer_id, amount, account_name)| {
94+
Payment { customer_id, amount, account_name }
95+
},
96+
)?;
97+
98+
// Let's make sure, that `payments` equals to `selected_payments`.
99+
// Mysql gives no guaranties on order of returned rows
100+
// without `ORDER BY`, so assume we are lucky.
101+
assert_eq!(payments, selected_payments);
102+
println!("Yay!");
103+
104+
Ok(())
105+
}
100106
```
101107

102108
### Crate Features
@@ -404,6 +410,17 @@ for i in 0..row.len() {
404410
assert_eq!(row[i], Value::Int(i as i64));
405411
}
406412

413+
// Another way to handle wide rows is to use HList (requires `mysql_common/frunk` feature)
414+
use frunk::{HList, hlist, hlist_pat};
415+
let query = "select 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15";
416+
type RowType = HList!(u8, u16, u32, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8);
417+
let first_three_columns = conn.query_map(query, |row: RowType| {
418+
// do something with the row (see the `frunk` crate documentation)
419+
let hlist_pat![c1, c2, c3, ...] = row;
420+
(c1, c2, c3)
421+
});
422+
assert_eq!(first_three_columns.unwrap(), vec![(0_u8, 1_u16, 2_u32)]);
423+
407424
// Some unknown row
408425
let row: Row = conn.query_first(
409426
// ...

azure-pipelines.yml

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,11 @@ jobs:
4545
SSL=false COMPRESS=true cargo test
4646
SSL=true COMPRESS=true cargo test
4747
48-
SSL=true COMPRESS=false cargo test --no-default-features --features rustls-tls,flate2/zlib,mysql_common/time03
49-
SSL=true COMPRESS=true cargo test --no-default-features --features rustls-tls,flate2/zlib,mysql_common/time03
48+
SSL=true COMPRESS=false cargo test --no-default-features --features rustls-tls,flate2/zlib,mysql_common/time03,mysql_common/frunk
49+
SSL=true COMPRESS=true cargo test --no-default-features --features rustls-tls,flate2/zlib,mysql_common/time03,mysql_common/frunk
5050
51-
SSL=false COMPRESS=true cargo test --no-default-features --features flate2/zlib,mysql_common/time03
52-
SSL=false COMPRESS=false cargo test --no-default-features --features flate2/zlib,mysql_common/time03
51+
SSL=false COMPRESS=true cargo test --no-default-features --features flate2/zlib,mysql_common/time03,mysql_common/frunk
52+
SSL=false COMPRESS=false cargo test --no-default-features --features flate2/zlib,mysql_common/time03,mysql_common/frunk
5353
env:
5454
RUST_BACKTRACE: 1
5555
DATABASE_URL: mysql://root:root@localhost:3306/mysql
@@ -91,11 +91,11 @@ jobs:
9191
SSL=false COMPRESS=true cargo test
9292
SSL=true COMPRESS=true cargo test
9393
94-
SSL=true COMPRESS=false cargo test --no-default-features --features rustls-tls,flate2/zlib,mysql_common/time03
95-
SSL=true COMPRESS=true cargo test --no-default-features --features rustls-tls,flate2/zlib,mysql_common/time03
94+
SSL=true COMPRESS=false cargo test --no-default-features --features rustls-tls,flate2/zlib,mysql_common/time03,mysql_common/frunk
95+
SSL=true COMPRESS=true cargo test --no-default-features --features rustls-tls,flate2/zlib,mysql_common/time03,mysql_common/frunk
9696
97-
SSL=false COMPRESS=true cargo test --no-default-features --features flate2/zlib,mysql_common/time03
98-
SSL=false COMPRESS=false cargo test --no-default-features --features flate2/zlib,mysql_common/time03
97+
SSL=false COMPRESS=true cargo test --no-default-features --features flate2/zlib,mysql_common/time03,mysql_common/frunk
98+
SSL=false COMPRESS=false cargo test --no-default-features --features flate2/zlib,mysql_common/time03,mysql_common/frunk
9999
env:
100100
RUST_BACKTRACE: 1
101101
DATABASE_URL: mysql://root@localhost/mysql
@@ -142,11 +142,11 @@ jobs:
142142
SSL=false COMPRESS=true cargo test
143143
SSL=true COMPRESS=true cargo test
144144
145-
SSL=true COMPRESS=false cargo test --no-default-features --features rustls-tls,flate2/zlib,mysql_common/time03
146-
SSL=true COMPRESS=true cargo test --no-default-features --features rustls-tls,flate2/zlib,mysql_common/time03
145+
SSL=true COMPRESS=false cargo test --no-default-features --features rustls-tls,flate2/zlib,mysql_common/time03,mysql_common/frunk
146+
SSL=true COMPRESS=true cargo test --no-default-features --features rustls-tls,flate2/zlib,mysql_common/time03,mysql_common/frunk
147147
148-
SSL=false COMPRESS=true cargo test --no-default-features --features flate2/zlib,mysql_common/time03
149-
SSL=false COMPRESS=false cargo test --no-default-features --features flate2/zlib,mysql_common/time03
148+
SSL=false COMPRESS=true cargo test --no-default-features --features flate2/zlib,mysql_common/time03,mysql_common/frunk
149+
SSL=false COMPRESS=false cargo test --no-default-features --features flate2/zlib,mysql_common/time03,mysql_common/frunk
150150
env:
151151
RUST_BACKTRACE: 1
152152
DATABASE_URL: mysql://root:password@localhost/mysql
@@ -214,11 +214,11 @@ jobs:
214214
docker exec container bash -l -c "cd \$HOME && DATABASE_URL=$DATABASE_URL SSL=$SSL cargo test"
215215
docker exec container bash -l -c "cd \$HOME && DATABASE_URL=$DATABASE_URL SSL=$SSL COMPRESS=true cargo test"
216216
217-
docker exec container bash -l -c "cd \$HOME && DATABASE_URL=$DATABASE_URL SSL=true COMPRESS=false cargo test --no-default-features --features rustls-tls,flate2/zlib,mysql_common/time03"
218-
docker exec container bash -l -c "cd \$HOME && DATABASE_URL=$DATABASE_URL SSL=true COMPRESS=true cargo test --no-default-features --features rustls-tls,flate2/zlib,mysql_common/time03"
217+
docker exec container bash -l -c "cd \$HOME && DATABASE_URL=$DATABASE_URL SSL=true COMPRESS=false cargo test --no-default-features --features rustls-tls,flate2/zlib,mysql_common/time03,mysql_common/frunk"
218+
docker exec container bash -l -c "cd \$HOME && DATABASE_URL=$DATABASE_URL SSL=true COMPRESS=true cargo test --no-default-features --features rustls-tls,flate2/zlib,mysql_common/time03,mysql_common/frunk"
219219
220-
docker exec container bash -l -c "cd \$HOME && DATABASE_URL=$DATABASE_URL SSL=false COMPRESS=true cargo test --no-default-features --features flate2/zlib,mysql_common/time03"
221-
docker exec container bash -l -c "cd \$HOME && DATABASE_URL=$DATABASE_URL SSL=false COMPRESS=false cargo test --no-default-features --features flate2/zlib,mysql_common/time03"
220+
docker exec container bash -l -c "cd \$HOME && DATABASE_URL=$DATABASE_URL SSL=false COMPRESS=true cargo test --no-default-features --features flate2/zlib,mysql_common/time03,mysql_common/frunk"
221+
docker exec container bash -l -c "cd \$HOME && DATABASE_URL=$DATABASE_URL SSL=false COMPRESS=false cargo test --no-default-features --features flate2/zlib,mysql_common/time03,mysql_common/frunk"
222222
env:
223223
RUST_BACKTRACE: 1
224224
DATABASE_URL: mysql://root:password@localhost/mysql
@@ -286,11 +286,11 @@ jobs:
286286
docker exec container bash -l -c "cd \$HOME && DATABASE_URL=$DATABASE_URL SSL=true cargo test"
287287
docker exec container bash -l -c "cd \$HOME && DATABASE_URL=$DATABASE_URL SSL=true COMPRESS=true cargo test"
288288
289-
docker exec container bash -l -c "cd \$HOME && DATABASE_URL=$DATABASE_URL SSL=true COMPRESS=false cargo test --no-default-features --features rustls-tls,flate2/zlib,mysql_common/time03"
290-
docker exec container bash -l -c "cd \$HOME && DATABASE_URL=$DATABASE_URL SSL=true COMPRESS=true cargo test --no-default-features --features rustls-tls,flate2/zlib,mysql_common/time03"
289+
docker exec container bash -l -c "cd \$HOME && DATABASE_URL=$DATABASE_URL SSL=true COMPRESS=false cargo test --no-default-features --features rustls-tls,flate2/zlib,mysql_common/time03,mysql_common/frunk"
290+
docker exec container bash -l -c "cd \$HOME && DATABASE_URL=$DATABASE_URL SSL=true COMPRESS=true cargo test --no-default-features --features rustls-tls,flate2/zlib,mysql_common/time03,mysql_common/frunk"
291291
292-
docker exec container bash -l -c "cd \$HOME && DATABASE_URL=$DATABASE_URL SSL=false COMPRESS=true cargo test --no-default-features --features flate2/zlib,mysql_common/time03"
293-
docker exec container bash -l -c "cd \$HOME && DATABASE_URL=$DATABASE_URL SSL=false COMPRESS=false cargo test --no-default-features --features flate2/zlib,mysql_common/time03"
292+
docker exec container bash -l -c "cd \$HOME && DATABASE_URL=$DATABASE_URL SSL=false COMPRESS=true cargo test --no-default-features --features flate2/zlib,mysql_common/time03,mysql_common/frunk"
293+
docker exec container bash -l -c "cd \$HOME && DATABASE_URL=$DATABASE_URL SSL=false COMPRESS=false cargo test --no-default-features --features flate2/zlib,mysql_common/time03,mysql_common/frunk"
294294
env:
295295
RUST_BACKTRACE: 1
296296
DATABASE_URL: mysql://root:password@localhost/mysql

src/lib.rs

Lines changed: 67 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@
4141
//! ## Example
4242
//!
4343
//! ```rust
44-
//! # mysql::doctest_wrapper!(__result, {
4544
//! use mysql::*;
4645
//! use mysql::prelude::*;
4746
//!
@@ -52,56 +51,60 @@
5251
//! account_name: Option<String>,
5352
//! }
5453
//!
55-
//! let url = "mysql://root:password@localhost:3307/db_name";
56-
//! # Opts::try_from(url)?;
57-
//! # let url = get_opts();
58-
//!
59-
//! let pool = Pool::new(url)?;
60-
//!
61-
//! let mut conn = pool.get_conn()?;
62-
//!
63-
//! // Let's create a table for payments.
64-
//! conn.query_drop(
65-
//! r"CREATE TEMPORARY TABLE payment (
66-
//! customer_id int not null,
67-
//! amount int not null,
68-
//! account_name text
69-
//! )")?;
70-
//!
71-
//! let payments = vec![
72-
//! Payment { customer_id: 1, amount: 2, account_name: None },
73-
//! Payment { customer_id: 3, amount: 4, account_name: Some("foo".into()) },
74-
//! Payment { customer_id: 5, amount: 6, account_name: None },
75-
//! Payment { customer_id: 7, amount: 8, account_name: None },
76-
//! Payment { customer_id: 9, amount: 10, account_name: Some("bar".into()) },
77-
//! ];
78-
//!
79-
//! // Now let's insert payments to the database
80-
//! conn.exec_batch(
81-
//! r"INSERT INTO payment (customer_id, amount, account_name)
82-
//! VALUES (:customer_id, :amount, :account_name)",
83-
//! payments.iter().map(|p| params! {
84-
//! "customer_id" => p.customer_id,
85-
//! "amount" => p.amount,
86-
//! "account_name" => &p.account_name,
87-
//! })
88-
//! )?;
89-
//!
90-
//! // Let's select payments from database. Type inference should do the trick here.
91-
//! let selected_payments = conn
92-
//! .query_map(
93-
//! "SELECT customer_id, amount, account_name from payment",
94-
//! |(customer_id, amount, account_name)| {
95-
//! Payment { customer_id, amount, account_name }
96-
//! },
54+
//! # def_get_opts!();
55+
//!
56+
//! fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
57+
//! let url = "mysql://root:password@localhost:3307/db_name";
58+
//! # Opts::try_from(url)?;
59+
//! # let url = get_opts();
60+
//! let pool = Pool::new(url)?;
61+
//!
62+
//! let mut conn = pool.get_conn()?;
63+
//!
64+
//! // Let's create a table for payments.
65+
//! conn.query_drop(
66+
//! r"CREATE TEMPORARY TABLE payment (
67+
//! customer_id int not null,
68+
//! amount int not null,
69+
//! account_name text
70+
//! )")?;
71+
//!
72+
//! let payments = vec![
73+
//! Payment { customer_id: 1, amount: 2, account_name: None },
74+
//! Payment { customer_id: 3, amount: 4, account_name: Some("foo".into()) },
75+
//! Payment { customer_id: 5, amount: 6, account_name: None },
76+
//! Payment { customer_id: 7, amount: 8, account_name: None },
77+
//! Payment { customer_id: 9, amount: 10, account_name: Some("bar".into()) },
78+
//! ];
79+
//!
80+
//! // Now let's insert payments to the database
81+
//! conn.exec_batch(
82+
//! r"INSERT INTO payment (customer_id, amount, account_name)
83+
//! VALUES (:customer_id, :amount, :account_name)",
84+
//! payments.iter().map(|p| params! {
85+
//! "customer_id" => p.customer_id,
86+
//! "amount" => p.amount,
87+
//! "account_name" => &p.account_name,
88+
//! })
9789
//! )?;
9890
//!
99-
//! // Let's make sure, that `payments` equals to `selected_payments`.
100-
//! // Mysql gives no guaranties on order of returned rows
101-
//! // without `ORDER BY`, so assume we are lucky.
102-
//! assert_eq!(payments, selected_payments);
103-
//! println!("Yay!");
104-
//! # });
91+
//! // Let's select payments from database. Type inference should do the trick here.
92+
//! let selected_payments = conn
93+
//! .query_map(
94+
//! "SELECT customer_id, amount, account_name from payment",
95+
//! |(customer_id, amount, account_name)| {
96+
//! Payment { customer_id, amount, account_name }
97+
//! },
98+
//! )?;
99+
//!
100+
//! // Let's make sure, that `payments` equals to `selected_payments`.
101+
//! // Mysql gives no guaranties on order of returned rows
102+
//! // without `ORDER BY`, so assume we are lucky.
103+
//! assert_eq!(payments, selected_payments);
104+
//! println!("Yay!");
105+
//!
106+
//! Ok(())
107+
//! }
105108
//! ```
106109
//!
107110
//! ## Crate Features
@@ -129,17 +132,17 @@
129132
//! * **mysql_common/uuid** – the `uuid` is enabled by default
130133
//! * **mysql_common/frunk** – the `frunk` is enabled by default
131134
//!
132-
//! Please note, that you'll need to reenable external features if you are using `no-default-features = true`:
135+
//! Please note, that you'll need to reenable external features if you are using `default-features = false`:
133136
//!
134137
//! ```toml
135138
//! [dependencies]
136139
//! # Lets say that we want to use the `rustls-tls` feature:
137-
//! mysql = { version = "*", no-default-features = true, features = ["rustls-tls", "buffer-pool"] }
140+
//! mysql = { version = "*", default-features = false, features = ["rustls-tls", "buffer-pool"] }
138141
//! # Previous line disables default mysql features,
139142
//! # so now we have to choose the flate2 backend (this is necessary),
140143
//! # as well as the desired set of mysql_common features:
141-
//! flate2 = { version = "*", no-default-features = true, features = ["zlib"] }
142-
//! mysql_common = { version = "*", no-default-features = true, features = ["bigdecimal03", "time03", "uuid"]}
144+
//! flate2 = { version = "*", default-features = false, features = ["zlib"] }
145+
//! mysql_common = { version = "*", default-features = false, features = ["bigdecimal03", "time03", "uuid"]}
143146
//! ```
144147
//!
145148
//! ## API Documentation
@@ -425,6 +428,17 @@
425428
//! assert_eq!(row[i], Value::Int(i as i64));
426429
//! }
427430
//!
431+
//! // Another way to handle wide rows is to use HList (requires `mysql_common/frunk` feature)
432+
//! use frunk::{HList, hlist, hlist_pat};
433+
//! let query = "select 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15";
434+
//! type RowType = HList!(u8, u16, u32, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8);
435+
//! let first_three_columns = conn.query_map(query, |row: RowType| {
436+
//! // do something with the row (see the `frunk` crate documentation)
437+
//! let hlist_pat![c1, c2, c3, ...] = row;
438+
//! (c1, c2, c3)
439+
//! });
440+
//! assert_eq!(first_three_columns.unwrap(), vec![(0_u8, 1_u16, 2_u32)]);
441+
//!
428442
//! // Some unknown row
429443
//! let row: Row = conn.query_first(
430444
//! // ...

0 commit comments

Comments
 (0)