mirror of
https://github.com/launchbadge/sqlx
synced 2024-11-10 06:24:16 +00:00
Use create_new
instead of atomic-file-write
(#2914)
* Use `create_new` instead of `atomic-file-write` This provides the same functionality but without temporary files, platform-specific code, fragility of `O_TMPFILE` support, and an extra dependency. * Properly handle acceptable failure cases * Consider `PermissionDenied` as acceptable Apparently this can occur on Windows. --------- Co-authored-by: Austin Bonander <austin.bonander@gmail.com>
This commit is contained in:
parent
02f196b4ac
commit
b615d2a826
3 changed files with 31 additions and 46 deletions
37
Cargo.lock
generated
37
Cargo.lock
generated
|
@ -334,16 +334,6 @@ version = "1.1.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"
|
||||
|
||||
[[package]]
|
||||
name = "atomic-write-file"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c232177ba50b16fe7a4588495bd474a62a9e45a8e4ca6fd7d0b7ac29d164631e"
|
||||
dependencies = [
|
||||
"nix 0.26.4",
|
||||
"rand",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "atty"
|
||||
version = "0.2.14"
|
||||
|
@ -1916,7 +1906,7 @@ version = "1.1.5"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4863ee94f19ed315bf3bc00299338d857d4b5bc856af375cc97d237382ad3856"
|
||||
dependencies = [
|
||||
"nix 0.23.2",
|
||||
"nix",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
|
@ -1951,15 +1941,6 @@ dependencies = [
|
|||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memoffset"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memoffset"
|
||||
version = "0.9.0"
|
||||
|
@ -2069,19 +2050,6 @@ dependencies = [
|
|||
"memoffset 0.6.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nix"
|
||||
version = "0.26.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"memoffset 0.7.1",
|
||||
"pin-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nom"
|
||||
version = "7.1.3"
|
||||
|
@ -2848,7 +2816,7 @@ dependencies = [
|
|||
"libc",
|
||||
"log",
|
||||
"memchr",
|
||||
"nix 0.23.2",
|
||||
"nix",
|
||||
"radix_trie",
|
||||
"scopeguard",
|
||||
"smallvec",
|
||||
|
@ -3402,7 +3370,6 @@ name = "sqlx-macros-core"
|
|||
version = "0.7.3"
|
||||
dependencies = [
|
||||
"async-std",
|
||||
"atomic-write-file",
|
||||
"dotenvy",
|
||||
"either",
|
||||
"heck 0.4.1",
|
||||
|
|
|
@ -48,7 +48,6 @@ tokio = { workspace = true, optional = true }
|
|||
|
||||
dotenvy = { workspace = true }
|
||||
|
||||
atomic-write-file = { version = "0.1" }
|
||||
hex = { version = "0.4.3" }
|
||||
heck = { version = "0.4", features = ["unicode"] }
|
||||
either = "1.6.1"
|
||||
|
|
|
@ -151,22 +151,41 @@ where
|
|||
}
|
||||
|
||||
pub(super) fn save_in(&self, dir: impl AsRef<Path>) -> crate::Result<()> {
|
||||
let path = dir.as_ref().join(format!("query-{}.json", self.hash));
|
||||
let mut file = atomic_write_file::AtomicWriteFile::open(&path)
|
||||
.map_err(|err| format!("failed to open the temporary file: {err:?}"))?;
|
||||
use std::io::ErrorKind;
|
||||
|
||||
serde_json::to_writer_pretty(file.as_file_mut(), self)
|
||||
.map_err(|err| format!("failed to serialize query data to file: {err:?}"))?;
|
||||
let path = dir.as_ref().join(format!("query-{}.json", self.hash));
|
||||
match std::fs::remove_file(&path) {
|
||||
Ok(()) => {}
|
||||
Err(err)
|
||||
if matches!(
|
||||
err.kind(),
|
||||
ErrorKind::NotFound | ErrorKind::PermissionDenied,
|
||||
) => {}
|
||||
Err(err) => return Err(format!("failed to delete {path:?}: {err:?}").into()),
|
||||
}
|
||||
let mut file = match std::fs::OpenOptions::new()
|
||||
.write(true)
|
||||
.create_new(true)
|
||||
.open(&path)
|
||||
{
|
||||
Ok(file) => file,
|
||||
// We overlapped with a concurrent invocation and the other one succeeded.
|
||||
Err(err) if matches!(err.kind(), ErrorKind::AlreadyExists) => return Ok(()),
|
||||
Err(err) => {
|
||||
return Err(format!("failed to exclusively create {path:?}: {err:?}").into())
|
||||
}
|
||||
};
|
||||
|
||||
let data = serde_json::to_string_pretty(self)
|
||||
.map_err(|err| format!("failed to serialize query data: {err:?}"))?;
|
||||
file.write_all(data.as_bytes())
|
||||
.map_err(|err| format!("failed to write query data to file: {err:?}"))?;
|
||||
|
||||
// Ensure there is a newline at the end of the JSON file to avoid
|
||||
// accidental modification by IDE and make github diff tool happier.
|
||||
file.as_file_mut()
|
||||
.write_all(b"\n")
|
||||
file.write_all(b"\n")
|
||||
.map_err(|err| format!("failed to append a newline to file: {err:?}"))?;
|
||||
|
||||
file.commit()
|
||||
.map_err(|err| format!("failed to commit the query data to {path:?}: {err:?}"))?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue