use crate::files;
use crate::{SETTINGS, STORE};
use async_std::{fs, io::ErrorKind, net::SocketAddr, path::Path, path::PathBuf};
use fehler::{throw, throws};
use http_types::{ensure, Error};
use itertools::iproduct;
use oxigraph::store::rocksdb::RocksDbStore;
#[derive(Debug)]
pub struct Config {
pub file_path: PathBuf,
pub db_path: PathBuf,
pub addr: SocketAddr,
}
#[throws]
fn configure() {
let mut settings = config::Config::default();
settings.set_default("file_path", "/srv/sparqlpuppy/files/")?;
settings.set_default("db_path", "/srv/sparqlpuppy/db/")?;
settings.set_default("addr", "127.0.0.1:8080")?;
settings.merge(config::Environment::with_prefix("SPARQLPUPPY"))?;
SETTINGS
.set(Config {
file_path: settings.get_str("file_path")?.into(),
db_path: settings.get_str("db_path")?.into(),
addr: settings.get_str("addr")?.parse()?,
})
.unwrap()
}
#[throws]
async fn mkhier(path: impl AsRef<Path>) {
let m = fs::metadata(&path).await;
match m {
Err(e) => {
if e.kind() == ErrorKind::NotFound {
fs::create_dir_all(&path).await?
} else {
throw!(e)
}
}
Ok(m) => ensure!(
m.is_dir(),
"{:?} exists but is not a directory",
path.as_ref()
),
}
}
#[throws]
async fn create_filehier() {
let settings = SETTINGS.get().unwrap();
let hexits = [
Path::new("0"),
Path::new("1"),
Path::new("2"),
Path::new("3"),
Path::new("4"),
Path::new("5"),
Path::new("6"),
Path::new("7"),
Path::new("8"),
Path::new("9"),
Path::new("a"),
Path::new("b"),
Path::new("c"),
Path::new("d"),
Path::new("e"),
Path::new("f"),
];
let base = settings.file_path.as_path();
for (i, j, k) in iproduct!(&hexits, &hexits, &hexits) {
let path: PathBuf = [base, i, j, k].iter().collect();
mkhier(path).await?
}
let path: PathBuf = [base, Path::new("ephem")].iter().collect();
fs::remove_dir_all(&path).await?;
mkhier(path).await?;
}
#[throws]
pub async fn setup() {
configure()?;
create_filehier().await?;
let settings = SETTINGS.get().unwrap();
ensure!(
STORE.set(RocksDbStore::open(&settings.db_path)?).is_ok(),
"Can't happen: Unable to store database handle."
);
}