Skip to content

Commit e881490

Browse files
authored
Merge branch 'launchbadge:main' into add-citext-support-postgres
2 parents 065eff4 + 253d8c9 commit e881490

File tree

26 files changed

+957
-357
lines changed

26 files changed

+957
-357
lines changed

Cargo.lock

+263-50
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+18-9
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ members = [
2323
]
2424

2525
[workspace.package]
26-
version = "0.7.0-alpha.2"
26+
version = "0.7.0-alpha.3"
2727
license = "MIT OR Apache-2.0"
2828
edition = "2021"
2929
repository = "https://github.com/launchbadge/sqlx"
@@ -114,17 +114,17 @@ regexp = ["sqlx-sqlite?/regexp"]
114114

115115
[workspace.dependencies]
116116
# Core Crates
117-
sqlx-core = { version = "=0.7.0-alpha.2", path = "sqlx-core" }
118-
sqlx-macros-core = { version = "=0.7.0-alpha.2", path = "sqlx-macros-core" }
119-
sqlx-macros = { version = "=0.7.0-alpha.2", path = "sqlx-macros" }
117+
sqlx-core = { version = "=0.7.0-alpha.3", path = "sqlx-core" }
118+
sqlx-macros-core = { version = "=0.7.0-alpha.3", path = "sqlx-macros-core" }
119+
sqlx-macros = { version = "=0.7.0-alpha.3", path = "sqlx-macros" }
120120

121121
# Driver crates
122-
sqlx-mysql = { version = "=0.7.0-alpha.2", path = "sqlx-mysql" }
123-
sqlx-postgres = { version = "=0.7.0-alpha.2", path = "sqlx-postgres" }
124-
sqlx-sqlite = { version = "=0.7.0-alpha.2", path = "sqlx-sqlite" }
122+
sqlx-mysql = { version = "=0.7.0-alpha.3", path = "sqlx-mysql" }
123+
sqlx-postgres = { version = "=0.7.0-alpha.3", path = "sqlx-postgres" }
124+
sqlx-sqlite = { version = "=0.7.0-alpha.3", path = "sqlx-sqlite" }
125125

126126
# Facade crate (for reference from sqlx-cli)
127-
sqlx = { version = "=0.7.0-alpha.2", path = "." }
127+
sqlx = { version = "=0.7.0-alpha.3", path = "." }
128128

129129
# Common type integrations shared by multiple driver crates.
130130
# These are optional unless enabled in a workspace crate.
@@ -175,8 +175,10 @@ rand = "0.8.4"
175175
rand_xoshiro = "0.6.0"
176176
hex = "0.4.3"
177177
tempdir = "0.3.7"
178+
criterion = {version = "0.4", features = ["async_tokio"]}
179+
178180
# Needed to test SQLCipher
179-
libsqlite3-sys = { version = "0.25.1", features = ["bundled-sqlcipher"] }
181+
libsqlite3-sys = { version = "0.26", features = ["bundled-sqlcipher"] }
180182

181183
#
182184
# Any
@@ -250,6 +252,12 @@ name = "sqlite-migrate"
250252
path = "tests/sqlite/migrate.rs"
251253
required-features = ["sqlite", "macros", "migrate"]
252254

255+
[[bench]]
256+
name = "sqlite-describe"
257+
path = "benches/sqlite/describe.rs"
258+
harness = false
259+
required-features = ["sqlite"]
260+
253261
#
254262
# MySQL
255263
#
@@ -332,3 +340,4 @@ required-features = ["postgres", "macros", "migrate"]
332340
name = "postgres-migrate"
333341
path = "tests/postgres/migrate.rs"
334342
required-features = ["postgres", "macros", "migrate"]
343+

README.md

+18-18
Original file line numberDiff line numberDiff line change
@@ -97,13 +97,13 @@ with C, those interactions are `unsafe`.
9797

9898
- Built-in connection pooling with `sqlx::Pool`.
9999

100-
- Row streaming. Data is read asynchronously from the database and decoded on-demand.
100+
- Row streaming. Data is read asynchronously from the database and decoded on demand.
101101

102102
- Automatic statement preparation and caching. When using the high-level query API (`sqlx::query`), statements are
103-
prepared and cached per-connection.
103+
prepared and cached per connection.
104104

105105
- Simple (unprepared) query execution including fetching results into the same `Row` types used by
106-
the high-level API. Supports batch execution and returning results from all statements.
106+
the high-level API. Supports batch execution and returns results from all statements.
107107

108108
- Transport Layer Security (TLS) where supported ([MySQL] and [PostgreSQL]).
109109

@@ -115,10 +115,10 @@ with C, those interactions are `unsafe`.
115115

116116
## Install
117117

118-
SQLx is compatible with the [`async-std`], [`tokio`] and [`actix`] runtimes; and, the [`native-tls`] and [`rustls`] TLS backends. When adding the dependency, you must chose a runtime feature that is `runtime` + `tls`.
118+
SQLx is compatible with the [`async-std`], [`tokio`], and [`actix`] runtimes; and, the [`native-tls`] and [`rustls`] TLS backends. When adding the dependency, you must choose a runtime feature that is `runtime` + `tls`.
119119

120120
NOTE: these examples are for the coming 0.7 release, which is currently in an alpha cycle.
121-
For the last stable release, 0.6.2, see [the previous verison of this document](https://github.com/launchbadge/sqlx/blob/v0.6.2/README.md).
121+
For the last stable release, 0.6.2, see [the previous version of this document](https://github.com/launchbadge/sqlx/blob/v0.6.2/README.md).
122122

123123
[`async-std`]: https://github.com/async-rs/async-std
124124
[`tokio`]: https://github.com/tokio-rs/tokio
@@ -148,10 +148,10 @@ sqlx = { version = "0.7", features = [ "runtime-async-std", "tls-rustls" ] }
148148

149149
#### Cargo Feature Flags
150150

151-
For backwards-compatibility reasons, the runtime and TLS features can either be chosen together as a single feature,
151+
For backward-compatibility reasons, the runtime and TLS features can either be chosen together as a single feature,
152152
or separately.
153153

154-
For forward-compatibility, you should use the separate runtime and TLS features as the combination features may
154+
For forward compatibility, you should use the separate runtime and TLS features as the combination features may
155155
be removed in the future.
156156

157157
- `runtime-async-std`: Use the `async-std` runtime without enabling a TLS backend.
@@ -170,7 +170,7 @@ be removed in the future.
170170

171171
- `tls-native`: Use the `native-tls` TLS backend (OpenSSL on *nix, SChannel on Windows, Secure Transport on macOS).
172172

173-
- `tls-rustls`: Use the `rustls` TLS backend (crossplatform backend, only supports TLS 1.2 and 1.3).
173+
- `tls-rustls`: Use the `rustls` TLS backend (cross-platform backend, only supports TLS 1.2 and 1.3).
174174

175175
- `postgres`: Add support for the Postgres database server.
176176

@@ -182,7 +182,7 @@ be removed in the future.
182182

183183
- `any`: Add support for the `Any` database driver, which can proxy to a database driver at runtime.
184184

185-
- `macros`: Add support for the `query*!` macros, which allow compile-time checked queries.
185+
- `macros`: Add support for the `query*!` macros, which allows compile-time checked queries.
186186

187187
- `migrate`: Add support for the migration management and `migrate!` macro, which allow compile-time embedded migrations.
188188

@@ -210,7 +210,7 @@ be removed in the future.
210210

211211
SQLx supports **compile-time checked queries**. It does not, however, do this by providing a Rust
212212
API or DSL (domain-specific language) for building queries. Instead, it provides macros that take
213-
regular SQL as an input and ensure that it is valid for your database. The way this works is that
213+
regular SQL as input and ensure that it is valid for your database. The way this works is that
214214
SQLx connects to your development DB at compile time to have the database itself verify (and return
215215
some info on) your SQL queries. This has some potentially surprising implications:
216216

@@ -231,7 +231,7 @@ See the `examples/` folder for more in-depth usage.
231231
### Quickstart
232232

233233
NOTE: these examples are for the coming 0.7.0 release, which is currently in an alpha cycle.
234-
For the last stable release, 0.6.2, see [the previous verison of this document](https://github.com/launchbadge/sqlx/blob/v0.6.2/README.md).
234+
For the last stable release, 0.6.2, see [the previous version of this document](https://github.com/launchbadge/sqlx/blob/v0.6.2/README.md).
235235

236236
```rust
237237
use sqlx::postgres::PgPoolOptions;
@@ -271,7 +271,7 @@ use sqlx::Connection;
271271
let conn = SqliteConnection::connect("sqlite::memory:").await?;
272272
```
273273

274-
Generally, you will want to instead create a connection pool (`sqlx::Pool`) in order for your application to
274+
Generally, you will want to instead create a connection pool (`sqlx::Pool`) for the application to
275275
regulate how many server-side connections it's using.
276276

277277
```rust
@@ -282,10 +282,10 @@ let pool = MySqlPool::connect("mysql://user:pass@host/database").await?;
282282

283283
In SQL, queries can be separated into prepared (parameterized) or unprepared (simple). Prepared queries have their
284284
query plan _cached_, use a binary mode of communication (lower bandwidth and faster decoding), and utilize parameters
285-
to avoid SQL injection. Unprepared queries are simple and intended only for use case where a prepared statement
285+
to avoid SQL injection. Unprepared queries are simple and intended only for use where a prepared statement
286286
will not work, such as various database commands (e.g., `PRAGMA` or `SET` or `BEGIN`).
287287

288-
SQLx supports all operations with both types of queries. In SQLx, a `&str` is treated as an unprepared query
288+
SQLx supports all operations with both types of queries. In SQLx, a `&str` is treated as an unprepared query,
289289
and a `Query` or `QueryAs` struct is treated as a prepared query.
290290

291291
```rust
@@ -294,7 +294,7 @@ conn.execute("BEGIN").await?; // unprepared, simple query
294294
conn.execute(sqlx::query("DELETE FROM table")).await?; // prepared, cached query
295295
```
296296

297-
We should prefer to use the high level, `query` interface whenever possible. To make this easier, there are finalizers
297+
We should prefer to use the high-level `query` interface whenever possible. To make this easier, there are finalizers
298298
on the type to avoid the need to wrap with an executor.
299299

300300
```rust
@@ -325,7 +325,7 @@ while let Some(row) = rows.try_next().await? {
325325
}
326326
```
327327

328-
To assist with mapping the row into a domain type, there are two idioms that may be used:
328+
To assist with mapping the row into a domain type, one of two idioms may be used:
329329

330330
```rust
331331
let mut stream = sqlx::query("SELECT * FROM users")
@@ -422,7 +422,7 @@ modifications (to the database-accessing parts of the code) are done, you can en
422422
to cache the results of the SQL query analysis using the `sqlx` command-line tool. See
423423
[sqlx-cli/README.md](./sqlx-cli/README.md#enable-building-in-offline-mode-with-query).
424424

425-
Compile time verified queries do quite a bit of work at compile time. Incremental actions like
425+
Compile-time verified queries do quite a bit of work at compile time. Incremental actions like
426426
`cargo check` and `cargo build` can be significantly faster when using an optimized build by
427427
putting the following in your `Cargo.toml` (More information in the
428428
[Profiles section](https://doc.rust-lang.org/cargo/reference/profiles.html) of The Cargo Book)
@@ -455,6 +455,6 @@ at your option.
455455

456456
## Contribution
457457

458-
Unless you explicitly state otherwise, any contribution intentionally submitted
458+
Unless you explicitly state otherwise, any Contribution intentionally submitted
459459
for inclusion in the work by you, as defined in the Apache-2.0 license, shall be
460460
dual licensed as above, without any additional terms or conditions.

benches/sqlite/describe.rs

+141
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
use criterion::BenchmarkId;
2+
use criterion::Criterion;
3+
use criterion::{criterion_group, criterion_main};
4+
5+
use sqlx::sqlite::{Sqlite, SqliteConnection};
6+
use sqlx::{Connection, Executor};
7+
use sqlx_test::new;
8+
9+
// Here we have an async function to benchmark
10+
async fn do_describe_trivial(db: &std::cell::RefCell<SqliteConnection>) {
11+
db.borrow_mut().describe("select 1").await.unwrap();
12+
}
13+
14+
async fn do_describe_recursive(db: &std::cell::RefCell<SqliteConnection>) {
15+
db.borrow_mut()
16+
.describe(
17+
r#"
18+
WITH RECURSIVE schedule(begin_date) AS MATERIALIZED (
19+
SELECT datetime('2022-10-01')
20+
WHERE datetime('2022-10-01') < datetime('2022-11-03')
21+
UNION ALL
22+
SELECT datetime(begin_date,'+1 day')
23+
FROM schedule
24+
WHERE datetime(begin_date) < datetime(?2)
25+
)
26+
SELECT
27+
begin_date
28+
FROM schedule
29+
GROUP BY begin_date
30+
"#,
31+
)
32+
.await
33+
.unwrap();
34+
}
35+
36+
async fn do_describe_insert(db: &std::cell::RefCell<SqliteConnection>) {
37+
db.borrow_mut()
38+
.describe("INSERT INTO tweet (id, text) VALUES (2, 'Hello') RETURNING *")
39+
.await
40+
.unwrap();
41+
}
42+
43+
async fn do_describe_insert_fks(db: &std::cell::RefCell<SqliteConnection>) {
44+
db.borrow_mut()
45+
.describe("insert into statements (text) values ('a') returning id")
46+
.await
47+
.unwrap();
48+
}
49+
50+
async fn init_connection() -> SqliteConnection {
51+
let mut conn = new::<Sqlite>().await.unwrap();
52+
53+
conn.execute(
54+
r#"
55+
CREATE TEMPORARY TABLE statements (
56+
id integer not null primary key,
57+
text text not null
58+
);
59+
60+
CREATE TEMPORARY TABLE votes1 (statement_id integer not null references statements(id));
61+
CREATE TEMPORARY TABLE votes2 (statement_id integer not null references statements(id));
62+
CREATE TEMPORARY TABLE votes3 (statement_id integer not null references statements(id));
63+
CREATE TEMPORARY TABLE votes4 (statement_id integer not null references statements(id));
64+
CREATE TEMPORARY TABLE votes5 (statement_id integer not null references statements(id));
65+
CREATE TEMPORARY TABLE votes6 (statement_id integer not null references statements(id));
66+
--CREATE TEMPORARY TABLE votes7 (statement_id integer not null references statements(id));
67+
--CREATE TEMPORARY TABLE votes8 (statement_id integer not null references statements(id));
68+
--CREATE TEMPORARY TABLE votes9 (statement_id integer not null references statements(id));
69+
--CREATE TEMPORARY TABLE votes10 (statement_id integer not null references statements(id));
70+
--CREATE TEMPORARY TABLE votes11 (statement_id integer not null references statements(id));
71+
"#,
72+
)
73+
.await
74+
.unwrap();
75+
conn
76+
}
77+
78+
fn describe_trivial(c: &mut Criterion) {
79+
let runtime = tokio::runtime::Runtime::new().unwrap();
80+
let db = std::cell::RefCell::new(runtime.block_on(init_connection()));
81+
82+
c.bench_with_input(
83+
BenchmarkId::new("select", "trivial"),
84+
&db,
85+
move |b, db_ref| {
86+
// Insert a call to `to_async` to convert the bencher to async mode.
87+
// The timing loops are the same as with the normal bencher.
88+
b.to_async(&runtime).iter(|| do_describe_trivial(db_ref));
89+
},
90+
);
91+
}
92+
93+
fn describe_recursive(c: &mut Criterion) {
94+
let runtime = tokio::runtime::Runtime::new().unwrap();
95+
let db = std::cell::RefCell::new(runtime.block_on(init_connection()));
96+
97+
c.bench_with_input(
98+
BenchmarkId::new("select", "recursive"),
99+
&db,
100+
move |b, db_ref| {
101+
// Insert a call to `to_async` to convert the bencher to async mode.
102+
// The timing loops are the same as with the normal bencher.
103+
b.to_async(&runtime).iter(|| do_describe_recursive(db_ref));
104+
},
105+
);
106+
}
107+
108+
fn describe_insert(c: &mut Criterion) {
109+
let runtime = tokio::runtime::Runtime::new().unwrap();
110+
let db = std::cell::RefCell::new(runtime.block_on(init_connection()));
111+
112+
c.bench_with_input(
113+
BenchmarkId::new("insert", "returning"),
114+
&db,
115+
move |b, db_ref| {
116+
// Insert a call to `to_async` to convert the bencher to async mode.
117+
// The timing loops are the same as with the normal bencher.
118+
b.to_async(&runtime).iter(|| do_describe_insert(db_ref));
119+
},
120+
);
121+
}
122+
123+
fn describe_insert_fks(c: &mut Criterion) {
124+
let runtime = tokio::runtime::Runtime::new().unwrap();
125+
let db = std::cell::RefCell::new(runtime.block_on(init_connection()));
126+
127+
c.bench_with_input(BenchmarkId::new("insert", "fks"), &db, move |b, db_ref| {
128+
// Insert a call to `to_async` to convert the bencher to async mode.
129+
// The timing loops are the same as with the normal bencher.
130+
b.to_async(&runtime).iter(|| do_describe_insert_fks(db_ref));
131+
});
132+
}
133+
134+
criterion_group!(
135+
benches,
136+
describe_trivial,
137+
describe_recursive,
138+
describe_insert,
139+
describe_insert_fks
140+
);
141+
criterion_main!(benches);

sqlx-core/Cargo.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,9 @@ tokio = { workspace = true, optional = true }
3636
# TLS
3737
native-tls = { version = "0.2.10", optional = true }
3838

39-
rustls = { version = "0.20.6", default-features = false, features = ["dangerous_configuration", "tls12"], optional = true }
39+
rustls = { version = "0.21", default-features = false, features = ["dangerous_configuration", "tls12"], optional = true }
4040
rustls-pemfile = { version = "1.0", optional = true }
41-
webpki-roots = { version = "0.22.0", optional = true }
41+
webpki-roots = { version = "0.23", optional = true }
4242

4343
# Type Integrations
4444
bit-vec = { workspace = true, optional = true }

sqlx-core/src/net/tls/tls_rustls.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ use std::time::SystemTime;
66

77
use rustls::{
88
client::{ServerCertVerified, ServerCertVerifier, WebPkiVerifier},
9-
ClientConfig, ClientConnection, Error as TlsError, OwnedTrustAnchor, RootCertStore, ServerName,
9+
CertificateError, ClientConfig, ClientConnection, Error as TlsError, OwnedTrustAnchor,
10+
RootCertStore, ServerName,
1011
};
1112

1213
use crate::error::Error;
@@ -234,8 +235,8 @@ impl ServerCertVerifier for NoHostnameTlsVerifier {
234235
ocsp_response,
235236
now,
236237
) {
237-
Err(TlsError::InvalidCertificateData(reason))
238-
if reason.contains("CertNotValidForName") =>
238+
Err(TlsError::InvalidCertificate(reason))
239+
if reason == CertificateError::NotValidForName =>
239240
{
240241
Ok(ServerCertVerified::assertion())
241242
}

sqlx-macros-core/src/lib.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@
1919
feature(track_path)
2020
)]
2121

22-
use once_cell::sync::Lazy;
23-
2422
use crate::query::QueryDriver;
2523

2624
pub type Error = Box<dyn std::error::Error>;
@@ -54,6 +52,7 @@ where
5452
{
5553
#[cfg(feature = "_rt-tokio")]
5654
{
55+
use once_cell::sync::Lazy;
5756
use tokio::runtime::{self, Runtime};
5857

5958
// We need a single, persistent Tokio runtime since we're caching connections,

0 commit comments

Comments
 (0)