Skip to content

Commit 2692f3c

Browse files
committed
refactor: make Config always compiled
simplifies usage while still making parsing optional for less generated code
1 parent 508983e commit 2692f3c

File tree

12 files changed

+114
-62
lines changed

12 files changed

+114
-62
lines changed

Cargo.toml

+3-5
Original file line numberDiff line numberDiff line change
@@ -54,16 +54,14 @@ features = ["all-databases", "_unstable-all-types", "_unstable-doc"]
5454
rustdoc-args = ["--cfg", "docsrs"]
5555

5656
[features]
57-
default = ["any", "macros", "migrate", "json", "config-all"]
57+
default = ["any", "macros", "migrate", "json", "sqlx-toml"]
5858

5959
derive = ["sqlx-macros/derive"]
6060
macros = ["derive", "sqlx-macros/macros"]
6161
migrate = ["sqlx-core/migrate", "sqlx-macros?/migrate", "sqlx-mysql?/migrate", "sqlx-postgres?/migrate", "sqlx-sqlite?/migrate"]
6262

63-
# Enable parsing of `sqlx.toml` for configuring macros, migrations, or both.
64-
config-macros = ["sqlx-macros?/config-macros"]
65-
config-migrate = ["sqlx-macros?/config-migrate"]
66-
config-all = ["config-macros", "config-migrate"]
63+
# Enable parsing of `sqlx.toml` for configuring macros and migrations.
64+
sqlx-toml = ["sqlx-core/sqlx-toml", "sqlx-macros?/sqlx-toml"]
6765

6866
# intended mainly for CI and docs
6967
all-databases = ["mysql", "sqlite", "postgres", "any"]

sqlx-cli/Cargo.toml

+4-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@ filetime = "0.2"
5151
backoff = { version = "0.4.0", features = ["futures", "tokio"] }
5252

5353
[features]
54-
default = ["postgres", "sqlite", "mysql", "native-tls", "completions"]
54+
default = ["postgres", "sqlite", "mysql", "native-tls", "completions", "config"]
55+
5556
rustls = ["sqlx/runtime-tokio-rustls"]
5657
native-tls = ["sqlx/runtime-tokio-native-tls"]
5758

@@ -65,6 +66,8 @@ openssl-vendored = ["openssl/vendored"]
6566

6667
completions = ["dep:clap_complete"]
6768

69+
sqlx-toml = ["sqlx/sqlx-toml"]
70+
6871
[dev-dependencies]
6972
assert_cmd = "2.0.11"
7073
tempfile = "3.10.1"

sqlx-core/Cargo.toml

+5-4
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,12 @@ _tls-none = []
3030
# support offline/decoupled building (enables serialization of `Describe`)
3131
offline = ["serde", "either/serde"]
3232

33-
config = ["serde", "toml/parse"]
34-
config-macros = ["config"]
35-
config-migrate = ["config"]
33+
# Enable parsing of `sqlx.toml`.
34+
# For simplicity, the `config` module is always enabled,
35+
# but this removes the codegen
36+
sqlx-toml = ["serde", "toml/parse"]
3637

37-
_unstable-doc = ["config-macros", "config-migrate"]
38+
_unstable-doc = ["sqlx-toml"]
3839

3940
[dependencies]
4041
# Runtimes

sqlx-core/src/config/common.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/// Configuration shared by multiple components.
2-
#[derive(Debug, Default, serde::Deserialize)]
2+
#[derive(Debug, Default)]
3+
#[cfg_attr(feature = "sqlx-toml", derive(serde::Deserialize))]
34
pub struct Config {
45
/// Override the database URL environment variable.
56
///
@@ -36,3 +37,9 @@ pub struct Config {
3637
/// and the ones used in `bar` will use `BAR_DATABASE_URL`.
3738
pub database_url_var: Option<String>,
3839
}
40+
41+
impl Config {
42+
pub fn database_url_var(&self) -> &str {
43+
self.database_url_var.as_deref().unwrap_or("DATABASE_URL")
44+
}
45+
}

sqlx-core/src/config/macros.rs

+8-4
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
use std::collections::BTreeMap;
22

33
/// Configuration for the `query!()` family of macros.
4-
#[derive(Debug, Default, serde::Deserialize)]
5-
#[serde(default)]
4+
#[derive(Debug, Default)]
5+
#[cfg_attr(feature = "sqlx-toml", derive(serde::Deserialize), serde(default))]
66
pub struct Config {
77
/// Specify the crate to use for mapping date/time types to Rust.
88
///
@@ -235,8 +235,12 @@ pub struct Config {
235235
}
236236

237237
/// The crate to use for mapping date/time types to Rust.
238-
#[derive(Debug, Default, PartialEq, Eq, serde::Deserialize)]
239-
#[serde(rename_all = "snake_case")]
238+
#[derive(Debug, Default, PartialEq, Eq)]
239+
#[cfg_attr(
240+
feature = "sqlx-toml",
241+
derive(serde::Deserialize),
242+
serde(rename_all = "snake_case")
243+
)]
240244
pub enum DateTimeCrate {
241245
/// Use whichever crate is enabled (`time` then `chrono`).
242246
#[default]

sqlx-core/src/config/migrate.rs

+14-6
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ use std::collections::BTreeSet;
1212
/// if the proper precautions are not taken.
1313
///
1414
/// Be sure you know what you are doing and that you read all relevant documentation _thoroughly_.
15-
#[derive(Debug, Default, serde::Deserialize)]
16-
#[serde(default)]
15+
#[derive(Debug, Default)]
16+
#[cfg_attr(feature = "sqlx-toml", derive(serde::Deserialize), serde(default))]
1717
pub struct Config {
1818
/// Override the name of the table used to track executed migrations.
1919
///
@@ -118,8 +118,12 @@ pub struct Config {
118118
}
119119

120120
/// The default type of migration that `sqlx migrate create` should create by default.
121-
#[derive(Debug, Default, PartialEq, Eq, serde::Deserialize)]
122-
#[serde(rename_all = "snake_case")]
121+
#[derive(Debug, Default, PartialEq, Eq)]
122+
#[cfg_attr(
123+
feature = "sqlx-toml",
124+
derive(serde::Deserialize),
125+
serde(rename_all = "snake_case")
126+
)]
123127
pub enum DefaultMigrationType {
124128
/// Create the same migration type as that of the latest existing migration,
125129
/// or `Simple` otherwise.
@@ -134,8 +138,12 @@ pub enum DefaultMigrationType {
134138
}
135139

136140
/// The default scheme that `sqlx migrate create` should use for version integers.
137-
#[derive(Debug, Default, PartialEq, Eq, serde::Deserialize)]
138-
#[serde(rename_all = "snake_case")]
141+
#[derive(Debug, Default, PartialEq, Eq)]
142+
#[cfg_attr(
143+
feature = "sqlx-toml",
144+
derive(serde::Deserialize),
145+
serde(rename_all = "snake_case")
146+
)]
139147
pub enum DefaultVersioning {
140148
/// Infer the versioning scheme from existing migrations:
141149
///

sqlx-core/src/config/mod.rs

+63-31
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
//!
88
//! See the [reference][`_reference`] for the full `sqlx.toml` file.
99
10+
use std::error::Error;
1011
use std::fmt::Debug;
1112
use std::io;
1213
use std::path::{Path, PathBuf};
@@ -23,15 +24,16 @@ pub mod common;
2324
/// Configuration for the `query!()` family of macros.
2425
///
2526
/// See [`macros::Config`] for details.
26-
#[cfg(feature = "config-macros")]
2727
pub mod macros;
2828

2929
/// Configuration for migrations when executed using `sqlx::migrate!()` or through `sqlx-cli`.
3030
///
3131
/// See [`migrate::Config`] for details.
32-
#[cfg(feature = "config-migrate")]
3332
pub mod migrate;
3433

34+
#[cfg(feature = "sqlx-toml")]
35+
mod sqlx_toml;
36+
3537
/// Reference for `sqlx.toml` files
3638
///
3739
/// Source: `sqlx-core/src/config/reference.toml`
@@ -41,11 +43,12 @@ pub mod migrate;
4143
/// ```
4244
pub mod _reference {}
4345

44-
#[cfg(test)]
46+
#[cfg(all(test, feature = "sqlx-toml"))]
4547
mod tests;
4648

4749
/// The parsed structure of a `sqlx.toml` file.
48-
#[derive(Debug, Default, serde::Deserialize)]
50+
#[derive(Debug, Default)]
51+
#[cfg_attr(feature = "sqlx-toml", derive(serde::Deserialize))]
4952
pub struct Config {
5053
/// Configuration shared by multiple components.
5154
///
@@ -55,21 +58,11 @@ pub struct Config {
5558
/// Configuration for the `query!()` family of macros.
5659
///
5760
/// See [`macros::Config`] for details.
58-
#[cfg_attr(
59-
docsrs,
60-
doc(cfg(any(feature = "config-all", feature = "config-macros")))
61-
)]
62-
#[cfg(feature = "config-macros")]
6361
pub macros: macros::Config,
6462

6563
/// Configuration for migrations when executed using `sqlx::migrate!()` or through `sqlx-cli`.
6664
///
6765
/// See [`migrate::Config`] for details.
68-
#[cfg_attr(
69-
docsrs,
70-
doc(cfg(any(feature = "config-all", feature = "config-migrate")))
71-
)]
72-
#[cfg(feature = "config-migrate")]
7366
pub migrate: migrate::Config,
7467
}
7568

@@ -90,13 +83,17 @@ pub enum ConfigError {
9083
std::env::VarError,
9184
),
9285

86+
/// No configuration file was found. Not necessarily fatal.
87+
#[error("config file {path:?} not found")]
88+
NotFound {
89+
path: PathBuf,
90+
},
91+
9392
/// An I/O error occurred while attempting to read the config file at `path`.
9493
///
95-
/// This includes [`io::ErrorKind::NotFound`].
96-
///
97-
/// [`Self::not_found_path()`] will return the path if the file was not found.
94+
/// If the error is [`io::ErrorKind::NotFound`], [`Self::NotFound`] is returned instead.
9895
#[error("error reading config file {path:?}")]
99-
Read {
96+
Io {
10097
path: PathBuf,
10198
#[source]
10299
error: io::Error,
@@ -108,19 +105,36 @@ pub enum ConfigError {
108105
#[error("error parsing config file {path:?}")]
109106
Parse {
110107
path: PathBuf,
108+
/// Type-erased [`toml::de::Error`].
111109
#[source]
112-
error: toml::de::Error,
110+
error: Box<dyn Error + Send + Sync + 'static>,
111+
},
112+
113+
/// A `sqlx.toml` file was found or specified, but the `sqlx-toml` feature is not enabled.
114+
#[error("SQLx found config file at {path:?} but the `sqlx-toml` feature was not enabled")]
115+
ParseDisabled {
116+
path: PathBuf
113117
},
114118
}
115119

116120
impl ConfigError {
121+
/// Create a [`ConfigError`] from a [`std::io::Error`].
122+
///
123+
/// Maps to either `NotFound` or `Io`.
124+
pub fn from_io(path: PathBuf, error: io::Error) -> Self {
125+
if error.kind() == io::ErrorKind::NotFound {
126+
Self::NotFound { path }
127+
} else {
128+
Self::Io { path, error }
129+
}
130+
}
131+
117132
/// If this error means the file was not found, return the path that was attempted.
118133
pub fn not_found_path(&self) -> Option<&Path> {
119-
match self {
120-
ConfigError::Read { path, error } if error.kind() == io::ErrorKind::NotFound => {
121-
Some(path)
122-
}
123-
_ => None,
134+
if let Self::NotFound { path } = self {
135+
Some(path)
136+
} else {
137+
None
124138
}
125139
}
126140
}
@@ -140,14 +154,22 @@ impl Config {
140154
/// If the file exists but an unrecoverable error was encountered while parsing it.
141155
pub fn from_crate() -> &'static Self {
142156
Self::try_from_crate().unwrap_or_else(|e| {
143-
if let Some(path) = e.not_found_path() {
144-
// Non-fatal
145-
tracing::debug!("Not reading config, file {path:?} not found (error: {e})");
146-
CACHE.get_or_init(Config::default)
147-
} else {
157+
match e {
158+
ConfigError::NotFound { path } => {
159+
// Non-fatal
160+
tracing::debug!("Not reading config, file {path:?} not found (error: {e})");
161+
CACHE.get_or_init(Config::default)
162+
}
163+
// FATAL ERRORS BELOW:
148164
// In the case of migrations,
149165
// we can't proceed with defaults as they may be completely wrong.
150-
panic!("failed to read sqlx config: {e}")
166+
e @ ConfigError::ParseDisabled { .. } => {
167+
// Only returned if the file exists but the feature is not enabled.
168+
panic!("{e}")
169+
}
170+
e => {
171+
panic!("failed to read sqlx config: {e}")
172+
}
151173
}
152174
})
153175
}
@@ -188,12 +210,13 @@ impl Config {
188210
})
189211
}
190212

213+
#[cfg(feature = "sqlx-toml")]
191214
fn read_from(path: PathBuf) -> Result<Self, ConfigError> {
192215
// The `toml` crate doesn't provide an incremental reader.
193216
let toml_s = match std::fs::read_to_string(&path) {
194217
Ok(toml) => toml,
195218
Err(error) => {
196-
return Err(ConfigError::Read { path, error });
219+
return Err(ConfigError::from_io(path, error));
197220
}
198221
};
199222

@@ -203,4 +226,13 @@ impl Config {
203226

204227
toml::from_str(&toml_s).map_err(|error| ConfigError::Parse { path, error })
205228
}
229+
230+
#[cfg(not(feature = "sqlx-toml"))]
231+
fn read_from(path: PathBuf) -> Result<Self, ConfigError> {
232+
match path.try_exists() {
233+
Ok(true) => Err(ConfigError::ParseDisabled { path }),
234+
Ok(false) => Err(ConfigError::NotFound { path }),
235+
Err(e) => Err(ConfigError::from_io(path, e))
236+
}
237+
}
206238
}

sqlx-core/src/config/tests.rs

-2
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ fn assert_common_config(config: &config::common::Config) {
2020
assert_eq!(config.database_url_var.as_deref(), Some("FOO_DATABASE_URL"));
2121
}
2222

23-
#[cfg(feature = "config-macros")]
2423
fn assert_macros_config(config: &config::macros::Config) {
2524
use config::macros::*;
2625

@@ -74,7 +73,6 @@ fn assert_macros_config(config: &config::macros::Config) {
7473
);
7574
}
7675

77-
#[cfg(feature = "config-migrate")]
7876
fn assert_migrate_config(config: &config::migrate::Config) {
7977
use config::migrate::*;
8078

sqlx-core/src/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,6 @@ pub mod any;
9191
#[cfg(feature = "migrate")]
9292
pub mod testing;
9393

94-
#[cfg(feature = "config")]
9594
pub mod config;
9695

9796
pub use error::{Error, Result};

sqlx-macros-core/Cargo.toml

+1-3
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,7 @@ derive = []
2323
macros = []
2424
migrate = ["sqlx-core/migrate"]
2525

26-
config = ["sqlx-core/config"]
27-
config-macros = ["config", "sqlx-core/config-macros"]
28-
config-migrate = ["config", "sqlx-core/config-migrate"]
26+
sqlx-toml = ["sqlx-core/sqlx-toml"]
2927

3028
# database
3129
mysql = ["sqlx-mysql"]

sqlx-macros-core/src/query/mod.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use crate::query::data::{hash_string, DynQueryData, QueryData};
1616
use crate::query::input::RecordType;
1717
use either::Either;
1818
use url::Url;
19+
use sqlx_core::config::Config;
1920

2021
mod args;
2122
mod data;
@@ -138,8 +139,12 @@ static METADATA: Lazy<Metadata> = Lazy::new(|| {
138139
let offline = env("SQLX_OFFLINE")
139140
.map(|s| s.eq_ignore_ascii_case("true") || s == "1")
140141
.unwrap_or(false);
141-
142-
let database_url = env("DATABASE_URL").ok();
142+
143+
let var_name = Config::from_crate()
144+
.common
145+
.database_url_var();
146+
147+
let database_url = env(var_name).ok();
143148

144149
Metadata {
145150
manifest_dir,

sqlx-macros/Cargo.toml

+1-2
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,7 @@ derive = ["sqlx-macros-core/derive"]
2626
macros = ["sqlx-macros-core/macros"]
2727
migrate = ["sqlx-macros-core/migrate"]
2828

29-
config-macros = ["sqlx-macros-core/config-macros"]
30-
config-migrate = ["sqlx-macros-core/config-migrate"]
29+
sqlx-toml = ["sqlx-macros-core/sqlx-toml"]
3130

3231
# database
3332
mysql = ["sqlx-macros-core/mysql"]

0 commit comments

Comments
 (0)