1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
//! This crate allow efficient async communication with Mariadb/Mysql
//!
//! You can either establish a raw connection using [Connection] or
//! use a [Pool] of connections.
//!
//! Drop handling
//! ------------
//!
//! When dropping/cancelling any future or struct returned by the library. The connections
//! will keep working. This is done by having the [Connection] have an internal state and
//! finish up any partially executed queries when the next query is executed or when [Connection::cleanup]
//! is called
//!
//! When dropping a [PoolConnection], any partial queries or transactions are finished up in
//! a spawned task. If this task takes too long to execute the connection is closed an a new
//! connection may be established.
//!
//! This means that if the qusql-mysql is used in a backend to handle web requests, and the
//! web request is cancelled while performing a long running query. Then the long running
//! query will be killed shortly after.
//!
//! Efficiency
//! -----------
//! We spawn very few tasks. Currently the only task spawned is
//! when a [PoolConnection] is dropped while there is a ongoing query or transaction.
//!
//! We have few memory allocations. In the cause of a normal
//! query, even one returning a string, no memory will be allocated
//!
//! The error types returned are all 8 bytes.
//!
//! The benchmark folder contains a benchmark that compares sqlx to qusql-mysql.
//! When run it shows the we are significantly more efficient than sqlx
//!
//! | Test | Qusql time | Sqlx time |
//! |---------------|--------------|--------------|
//! | Setup | 0.921 ms | 1.189 ms |
//! | Insert | 14218.778 ms | 15499.612 ms |
//! | Select all | 10968.823 ms | 15860.648 ms |
//! | Select stream | 9991.353 ms | 13215.973 ms |
//! | Select one | 19085.157 ms | 34728.834 ms |
//!
//! Feature flags
//! --------------
//! * stats: Add query count and timing statistics to the [Connection]
//! * chrono: Add bind and decode support for chrono DateTime and Time
//! * list_hack: Add support lists as arguments to queries
//!
//! Example
//! --------
//! ```no_run
//! use qusql_mysql::{Pool, ConnectionOptions, PoolOptions, ConnectionError, ExecutorExt, Executor};
//!
//! async fn test() -> Result<(), ConnectionError> {
//! let pool = Pool::connect(
//! ConnectionOptions::from_url("mysql://user:pw@127.0.0.1:3307/db").unwrap(),
//! PoolOptions::new().max_connections(10)
//! ).await?;
//!
//! let mut conn = pool.acquire().await?;
//!
//! let mut tr = conn.begin().await?;
//! tr.execute("INSERT INTO `table` (`v`, `t`) VALUES (?)", (42, "test_string")).await?;
//! tr.commit().await?;
//!
//! let rows: Vec<(i64, &str)> = conn.fetch_all("SELECT `v`, `t` FROM `table`", ()).await?;
//! Ok(())
//! }
//! ```
//!
//! List hack
//! ----------
//! If the list `list_hack` feature is enabled. Support for lists as arguments to queries is added
//! this is done done by adding a sufficient number of `?`'s to the query.
//!
//! ```no_run
//! # use qusql_mysql::{Connection, ExecutorExt, Executor, list, ConnectionError};
//! #[cfg(feature="list_hack")]
//! async fn test(conn: &mut Connection, vs: &[u32]) -> Result<(), ConnectionError> {
//! let rows: Vec<(i64, &str)> = conn.fetch_all(
//! "SELECT `v`, `t` FROM `table` WHERE `v` IN (_LIST_)", (list(vs),)).await?;
//! Ok(())
//! }
//! ```
//! Here the `_LIST_` is replaced with `?,?,..,?` where the number of `?`'s depend on the length
//! of the list. If the list is empty `_LIST_` is replaced by `NULL`
pub use ;
pub use ;
pub use ;
pub use Row;