Skip to content

Commit

Permalink
WIP: [offline] Remove sqlx-data.json and sqlx prepare command
Browse files Browse the repository at this point in the history
Query data is now stored in .sqlx/{query_hash}.json directly by the macro
invocations, rather than first writing to target/sqlx/{input_span_hash}.json
and then collecting those into sqlx-data.json separately.

WIP! Done: saving, ToDo: loading, removing prepare, updating docs
  • Loading branch information
jplatte committed Dec 30, 2020
1 parent 9b631ba commit 8e15d56
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 22 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion sqlx-macros/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ _rt-async-std = []
_rt-tokio = []

# offline building support
offline = ["sqlx-core/offline", "serde", "serde_json", "hex", "sha2"]
offline = ["sqlx-core/offline", "serde", "serde_json", "hex", "sha2", "tempfile"]

# database
mysql = [ "sqlx-core/mysql" ]
Expand Down Expand Up @@ -67,5 +67,6 @@ serde = { version = "1.0.111", optional = true }
serde_json = { version = "1.0.30", features = [ "preserve_order" ], optional = true }
sha2 = { version = "0.9.1", optional = true }
syn = { version = "1.0.30", default-features = false, features = [ "full" ] }
tempfile = { version = "3.1.0", optional = true }
quote = { version = "1.0.6", default-features = false }
url = { version = "2.1.1", default-features = false }
44 changes: 28 additions & 16 deletions sqlx-macros/src/query/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ pub mod offline {
use proc_macro2::Span;
use serde::de::{Deserializer, IgnoredAny, MapAccess, Visitor};
use sqlx_core::describe::Describe;
use tempfile::NamedTempFile;

#[derive(serde::Deserialize)]
pub struct DynQueryData {
Expand Down Expand Up @@ -99,22 +100,33 @@ pub mod offline {
}
}

pub fn save_in(&self, dir: impl AsRef<Path>, input_span: Span) -> crate::Result<()> {
// we save under the hash of the span representation because that should be unique
// per invocation
let path = dir.as_ref().join(format!(
"query-{}.json",
hash_string(&format!("{:?}", input_span))
));

serde_json::to_writer_pretty(
BufWriter::new(
File::create(&path)
.map_err(|e| format!("failed to open path {}: {}", path.display(), e))?,
),
self,
)
.map_err(Into::into)
pub fn save_in(&self, dir: impl AsRef<Path>) -> crate::Result<()> {
let dir = dir.as_ref();

// We first write to a temporary file to then move it to the final location.
// This ensures no file corruption happens in case this method is called concurrently
// for the same query.
let file = NamedTempFile::new_in(dir).map_err(|e| {
format!(
"failed to create temporary file in {}: {}",
dir.display(),
e,
)
})?;

serde_json::to_writer_pretty(BufWriter::new(&file), self)?;

let path = dir.join(format!("query-{}.json", hash_string(&self.query)));
file.persist(&path).map_err(|e| {
format!(
"failed to move temporary file {} to {}: {}",
e.file.path().display(),
path.display(),
e.error,
)
})?;

Ok(())
}
}

Expand Down
11 changes: 6 additions & 5 deletions sqlx-macros/src/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -309,14 +309,15 @@ where
// If the build is offline, the cache is our input so it's pointless to also write data for it.
#[cfg(feature = "offline")]
if !offline {
let mut save_dir = std::path::PathBuf::from(
env::var("CARGO_TARGET_DIR").unwrap_or_else(|_| "target/".into()),
);
use std::path::Path;

save_dir.push("sqlx");
let save_dir = env::var_os("CARGO_MANIFEST_DIR")
.map(Path::new)
.unwrap_or_else(|| Path::new("."))
.join(".sqlx");

std::fs::create_dir_all(&save_dir)?;
data.save_in(save_dir, input.src_span)?;
data.save_in(save_dir)?;
}

Ok(ret_tokens)
Expand Down

0 comments on commit 8e15d56

Please sign in to comment.