mirror of
https://github.com/launchbadge/sqlx.git
synced 2025-10-02 15:25:32 +00:00
sqlx-data.json removal prep work (#1184)
* macros: Reduce I/O by doing all .env and environment variable reading inside a Lazy initializer. * Use the default runtime and TLS backend for all examples Before, rust-analyzer was always hitting the "only one runtime can be enabled" compile_error in sqlx-rt.
This commit is contained in:
parent
13f7c7124a
commit
901f858fbc
@ -9,5 +9,5 @@ anyhow = "1.0"
|
|||||||
async-std = { version = "1.8.0", features = [ "attributes" ] }
|
async-std = { version = "1.8.0", features = [ "attributes" ] }
|
||||||
futures = "0.3"
|
futures = "0.3"
|
||||||
paw = "1.0"
|
paw = "1.0"
|
||||||
sqlx = { path = "../../../", features = [ "mysql", "runtime-async-std-rustls" ] }
|
sqlx = { path = "../../../", features = [ "mysql", "runtime-async-std-native-tls" ] }
|
||||||
structopt = { version = "0.3", features = [ "paw" ] }
|
structopt = { version = "0.3", features = [ "paw" ] }
|
||||||
|
@ -58,7 +58,7 @@ _rt-async-std = []
|
|||||||
_rt-tokio = []
|
_rt-tokio = []
|
||||||
|
|
||||||
# offline building support
|
# offline building support
|
||||||
offline = ["sqlx-core/offline", "hex", "once_cell", "serde", "serde_json", "sha2"]
|
offline = ["sqlx-core/offline", "hex", "serde", "serde_json", "sha2"]
|
||||||
|
|
||||||
# database
|
# database
|
||||||
mysql = ["sqlx-core/mysql"]
|
mysql = ["sqlx-core/mysql"]
|
||||||
@ -82,7 +82,7 @@ futures = { version = "0.3.4", default-features = false, features = ["executor"]
|
|||||||
hex = { version = "0.4.2", optional = true }
|
hex = { version = "0.4.2", optional = true }
|
||||||
heck = "0.3.1"
|
heck = "0.3.1"
|
||||||
either = "1.5.3"
|
either = "1.5.3"
|
||||||
once_cell = { version = "1.5.2", optional = true }
|
once_cell = "1.5.2"
|
||||||
proc-macro2 = { version = "1.0.9", default-features = false }
|
proc-macro2 = { version = "1.0.9", default-features = false }
|
||||||
sqlx-core = { version = "0.5.3", default-features = false, path = "../sqlx-core" }
|
sqlx-core = { version = "0.5.3", default-features = false, path = "../sqlx-core" }
|
||||||
sqlx-rt = { version = "0.5.3", default-features = false, path = "../sqlx-rt" }
|
sqlx-rt = { version = "0.5.3", default-features = false, path = "../sqlx-rt" }
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
use std::env;
|
|
||||||
use std::path::Path;
|
|
||||||
#[cfg(feature = "offline")]
|
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
use once_cell::sync::Lazy;
|
||||||
use proc_macro2::TokenStream;
|
use proc_macro2::TokenStream;
|
||||||
use syn::Type;
|
use syn::Type;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
@ -24,60 +22,96 @@ mod data;
|
|||||||
mod input;
|
mod input;
|
||||||
mod output;
|
mod output;
|
||||||
|
|
||||||
|
struct Metadata {
|
||||||
|
manifest_dir: PathBuf,
|
||||||
|
offline: bool,
|
||||||
|
database_url: Option<String>,
|
||||||
|
#[cfg(feature = "offline")]
|
||||||
|
target_dir: PathBuf,
|
||||||
|
#[cfg(feature = "offline")]
|
||||||
|
workspace_root: PathBuf,
|
||||||
|
}
|
||||||
|
|
||||||
// If we are in a workspace, lookup `workspace_root` since `CARGO_MANIFEST_DIR` won't
|
// If we are in a workspace, lookup `workspace_root` since `CARGO_MANIFEST_DIR` won't
|
||||||
// reflect the workspace dir: https://github.com/rust-lang/cargo/issues/3946
|
// reflect the workspace dir: https://github.com/rust-lang/cargo/issues/3946
|
||||||
|
static METADATA: Lazy<Metadata> = Lazy::new(|| {
|
||||||
|
use std::env;
|
||||||
|
|
||||||
|
let manifest_dir = env::var("CARGO_MANIFEST_DIR")
|
||||||
|
.expect("`CARGO_MANIFEST_DIR` must be set")
|
||||||
|
.into();
|
||||||
|
|
||||||
#[cfg(feature = "offline")]
|
#[cfg(feature = "offline")]
|
||||||
static CRATE_ROOT: once_cell::sync::Lazy<PathBuf> = once_cell::sync::Lazy::new(|| {
|
let target_dir =
|
||||||
|
env::var_os("CARGO_TARGET_DIR").map_or_else(|| "target".into(), |dir| dir.into());
|
||||||
|
|
||||||
|
// If a .env file exists at CARGO_MANIFEST_DIR, load environment variables from this,
|
||||||
|
// otherwise fallback to default dotenv behaviour.
|
||||||
|
let env_path = METADATA.manifest_dir.join(".env");
|
||||||
|
if env_path.exists() {
|
||||||
|
let res = dotenv::from_path(&env_path);
|
||||||
|
if let Err(e) = res {
|
||||||
|
panic!("failed to load environment from {:?}, {}", env_path, e);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let _ = dotenv::dotenv();
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Switch to `var_os` after feature(osstring_ascii) is stable.
|
||||||
|
// Stabilization PR: https://github.com/rust-lang/rust/pull/80193
|
||||||
|
let offline = env::var("SQLX_OFFLINE")
|
||||||
|
.map(|s| s.eq_ignore_ascii_case("true") || s == "1")
|
||||||
|
.unwrap_or(false);
|
||||||
|
|
||||||
|
let database_url = env::var("DATABASE_URL").ok();
|
||||||
|
|
||||||
|
#[cfg(feature = "offline")]
|
||||||
|
let workspace_root = {
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
|
|
||||||
let manifest_dir = env::var("CARGO_MANIFEST_DIR").expect("`CARGO_MANIFEST_DIR` must be set");
|
|
||||||
|
|
||||||
let cargo = env::var_os("CARGO").expect("`CARGO` must be set");
|
let cargo = env::var_os("CARGO").expect("`CARGO` must be set");
|
||||||
|
|
||||||
let output = Command::new(&cargo)
|
let output = Command::new(&cargo)
|
||||||
.args(&["metadata", "--format-version=1"])
|
.args(&["metadata", "--format-version=1"])
|
||||||
.current_dir(manifest_dir)
|
.current_dir(&manifest_dir)
|
||||||
.output()
|
.output()
|
||||||
.expect("Could not fetch metadata");
|
.expect("Could not fetch metadata");
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
struct Metadata {
|
struct CargoMetadata {
|
||||||
workspace_root: PathBuf,
|
workspace_root: PathBuf,
|
||||||
}
|
}
|
||||||
|
|
||||||
let metadata: Metadata =
|
let metadata: CargoMetadata =
|
||||||
serde_json::from_slice(&output.stdout).expect("Invalid `cargo metadata` output");
|
serde_json::from_slice(&output.stdout).expect("Invalid `cargo metadata` output");
|
||||||
|
|
||||||
metadata.workspace_root
|
metadata.workspace_root
|
||||||
|
};
|
||||||
|
|
||||||
|
Metadata {
|
||||||
|
manifest_dir,
|
||||||
|
offline,
|
||||||
|
database_url,
|
||||||
|
#[cfg(feature = "offline")]
|
||||||
|
target_dir,
|
||||||
|
#[cfg(feature = "offline")]
|
||||||
|
workspace_root,
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
pub fn expand_input(input: QueryMacroInput) -> crate::Result<TokenStream> {
|
pub fn expand_input(input: QueryMacroInput) -> crate::Result<TokenStream> {
|
||||||
let manifest_dir =
|
match &*METADATA {
|
||||||
env::var("CARGO_MANIFEST_DIR").map_err(|_| "`CARGO_MANIFEST_DIR` must be set")?;
|
Metadata {
|
||||||
|
offline: false,
|
||||||
// If a .env file exists at CARGO_MANIFEST_DIR, load environment variables from this,
|
database_url: Some(db_url),
|
||||||
// otherwise fallback to default dotenv behaviour.
|
..
|
||||||
let env_path = Path::new(&manifest_dir).join(".env");
|
} => expand_from_db(input, &db_url),
|
||||||
if env_path.exists() {
|
|
||||||
dotenv::from_path(&env_path)
|
|
||||||
.map_err(|e| format!("failed to load environment from {:?}, {}", env_path, e))?
|
|
||||||
}
|
|
||||||
|
|
||||||
// if `dotenv` wasn't initialized by the above we make sure to do it here
|
|
||||||
match (
|
|
||||||
dotenv::var("SQLX_OFFLINE")
|
|
||||||
.map(|s| s.eq_ignore_ascii_case("true") || s == "1")
|
|
||||||
.unwrap_or(false),
|
|
||||||
dotenv::var("DATABASE_URL"),
|
|
||||||
) {
|
|
||||||
(false, Ok(db_url)) => expand_from_db(input, &db_url),
|
|
||||||
|
|
||||||
#[cfg(feature = "offline")]
|
#[cfg(feature = "offline")]
|
||||||
_ => {
|
_ => {
|
||||||
let data_file_path = Path::new(&manifest_dir).join("sqlx-data.json");
|
let data_file_path = METADATA.manifest_dir.join("sqlx-data.json");
|
||||||
|
let workspace_data_file_path = METADATA.workspace_root.join("sqlx-data.json");
|
||||||
let workspace_data_file_path = CRATE_ROOT.join("sqlx-data.json");
|
|
||||||
|
|
||||||
if data_file_path.exists() {
|
if data_file_path.exists() {
|
||||||
expand_from_file(input, data_file_path)
|
expand_from_file(input, data_file_path)
|
||||||
@ -93,12 +127,16 @@ pub fn expand_input(input: QueryMacroInput) -> crate::Result<TokenStream> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "offline"))]
|
#[cfg(not(feature = "offline"))]
|
||||||
(true, _) => {
|
Metadata { offline: true, .. } => {
|
||||||
Err("The cargo feature `offline` has to be enabled to use `SQLX_OFFLINE`".into())
|
Err("The cargo feature `offline` has to be enabled to use `SQLX_OFFLINE`".into())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "offline"))]
|
#[cfg(not(feature = "offline"))]
|
||||||
(false, Err(_)) => Err("`DATABASE_URL` must be set to use query macros".into()),
|
Metadata {
|
||||||
|
offline: false,
|
||||||
|
database_url: None,
|
||||||
|
..
|
||||||
|
} => Err("`DATABASE_URL` must be set to use query macros".into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -322,11 +360,7 @@ where
|
|||||||
// If the build is offline, the cache is our input so it's pointless to also write data for it.
|
// If the build is offline, the cache is our input so it's pointless to also write data for it.
|
||||||
#[cfg(feature = "offline")]
|
#[cfg(feature = "offline")]
|
||||||
if !offline {
|
if !offline {
|
||||||
let mut save_dir =
|
let save_dir = METADATA.target_dir.join("sqlx");
|
||||||
PathBuf::from(env::var("CARGO_TARGET_DIR").unwrap_or_else(|_| "target/".into()));
|
|
||||||
|
|
||||||
save_dir.push("sqlx");
|
|
||||||
|
|
||||||
std::fs::create_dir_all(&save_dir)?;
|
std::fs::create_dir_all(&save_dir)?;
|
||||||
data.save_in(save_dir, input.src_span)?;
|
data.save_in(save_dir, input.src_span)?;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user