Server: Fixes support of --location before command name

pull/428/head
Tpt 2 years ago committed by Thomas Tanon
parent bf36e60b34
commit 3d61867386
  1. 100
      server/src/main.rs

@ -36,6 +36,11 @@ const LOGO: &str = include_str!("../logo.svg");
#[command(about, version)] #[command(about, version)]
/// Oxigraph SPARQL server. /// Oxigraph SPARQL server.
struct Args { struct Args {
/// Directory in which the data should be persisted.
///
/// If not present. An in-memory storage will be used.
#[arg(short, long, global = true)]
location: Option<PathBuf>, //TODO: move into commands on next breaking release
#[command(subcommand)] #[command(subcommand)]
command: Command, command: Command,
} }
@ -44,13 +49,8 @@ struct Args {
enum Command { enum Command {
/// Start Oxigraph HTTP server in read-write mode. /// Start Oxigraph HTTP server in read-write mode.
Serve { Serve {
/// Directory in which the data stored by Oxigraph should be persisted.
///
/// If not present. An in-memory storage will be used.
#[arg(short, long, global = true)]
location: Option<PathBuf>,
/// Host and port to listen to. /// Host and port to listen to.
#[arg(short, long, default_value = "localhost:7878", global = true)] #[arg(short, long, default_value = "localhost:7878")]
bind: String, bind: String,
}, },
/// Start Oxigraph HTTP server in read-only mode. /// Start Oxigraph HTTP server in read-only mode.
@ -59,9 +59,6 @@ enum Command {
/// Opening as read-only while having an other process writing the database is undefined behavior. /// Opening as read-only while having an other process writing the database is undefined behavior.
/// Please use the serve-secondary command in this case. /// Please use the serve-secondary command in this case.
ServeReadOnly { ServeReadOnly {
/// Directory in which the data stored by Oxigraph are persisted.
#[arg(short, long)]
location: PathBuf,
/// Host and port to listen to. /// Host and port to listen to.
#[arg(short, long, default_value = "localhost:7878")] #[arg(short, long, default_value = "localhost:7878")]
bind: String, bind: String,
@ -75,8 +72,8 @@ enum Command {
/// Dirty reads might happen. /// Dirty reads might happen.
ServeSecondary { ServeSecondary {
/// Directory where the primary Oxigraph instance is writing to. /// Directory where the primary Oxigraph instance is writing to.
#[arg(long, alias = "location", short_alias = 'l')] #[arg(long, conflicts_with = "location")]
primary_location: PathBuf, primary_location: Option<PathBuf>,
/// Directory to which the current secondary instance might write to. /// Directory to which the current secondary instance might write to.
/// ///
/// By default, temporary storage is used. /// By default, temporary storage is used.
@ -98,24 +95,18 @@ enum Command {
/// ///
/// If you want to move your data to another RDF storage system, you should use the dump operation instead. /// If you want to move your data to another RDF storage system, you should use the dump operation instead.
Backup { Backup {
/// Directory in which the data stored by Oxigraph are persisted.
#[arg(short, long)]
location: PathBuf,
/// Directory to backup to. /// Directory to backup to.
#[arg(short, long)] #[arg(short, long)]
destination: PathBuf, destination: PathBuf,
}, },
/// Load file(s) into the store. /// Load file(s) into the store.
Load { Load {
/// Directory in which the loaded data should be persisted.
#[arg(short, long, global = true)]
location: Option<PathBuf>, //TODO: make mandatory on next breaking release
/// File(s) to load. /// File(s) to load.
/// ///
/// If multiple files are provided they are loaded in parallel. /// If multiple files are provided they are loaded in parallel.
/// ///
/// If no file is given, stdin is read. /// If no file is given, stdin is read.
#[arg(short, long, global = true, num_args = 0..)] #[arg(short, long, num_args = 0..)]
file: Vec<PathBuf>, file: Vec<PathBuf>,
/// The format of the file(s) to load. /// The format of the file(s) to load.
/// ///
@ -127,7 +118,7 @@ enum Command {
/// Attempt to keep loading even if the data file is invalid. /// Attempt to keep loading even if the data file is invalid.
/// ///
/// Only works with N-Triples and N-Quads for now. /// Only works with N-Triples and N-Quads for now.
#[arg(long, global = true)] #[arg(long)]
lenient: bool, lenient: bool,
/// Name of the graph to load the data to. /// Name of the graph to load the data to.
/// ///
@ -139,9 +130,6 @@ enum Command {
}, },
/// Dump the store content into a file. /// Dump the store content into a file.
Dump { Dump {
/// Directory in which the data stored by Oxigraph are persisted.
#[arg(short, long)]
location: PathBuf,
/// File to dump to. /// File to dump to.
/// ///
/// If no file is given, stdout is used. /// If no file is given, stdout is used.
@ -162,9 +150,6 @@ enum Command {
}, },
/// Executes a SPARQL query against the store. /// Executes a SPARQL query against the store.
Query { Query {
/// Directory in which the data stored by Oxigraph are persisted.
#[arg(short, long)]
location: PathBuf,
/// The SPARQL query to execute. /// The SPARQL query to execute.
/// ///
/// If no query or query file are given, stdin is used. /// If no query or query file are given, stdin is used.
@ -193,9 +178,6 @@ enum Command {
}, },
/// Executes a SPARQL update against the store. /// Executes a SPARQL update against the store.
Update { Update {
/// Directory in which the data stored by Oxigraph are persisted.
#[arg(short, long)]
location: PathBuf,
/// The SPARQL update to execute. /// The SPARQL update to execute.
/// ///
/// If no query or query file are given, stdin is used. /// If no query or query file are given, stdin is used.
@ -215,8 +197,8 @@ enum Command {
pub fn main() -> anyhow::Result<()> { pub fn main() -> anyhow::Result<()> {
let matches = Args::parse(); let matches = Args::parse();
match matches.command { match matches.command {
Command::Serve { location, bind } => serve( Command::Serve { bind } => serve(
if let Some(location) = location { if let Some(location) = matches.location {
Store::open(location) Store::open(location)
} else { } else {
Store::new() Store::new()
@ -224,14 +206,24 @@ pub fn main() -> anyhow::Result<()> {
bind, bind,
false, false,
), ),
Command::ServeReadOnly { location, bind } => { Command::ServeReadOnly { bind } => serve(
serve(Store::open_read_only(location)?, bind, true) Store::open_read_only(
} matches
.location
.ok_or_else(|| anyhow!("The --location argument is required"))?,
)?,
bind,
true,
),
Command::ServeSecondary { Command::ServeSecondary {
primary_location, primary_location,
secondary_location, secondary_location,
bind, bind,
} => serve( } => {
let primary_location = primary_location.or(matches.location).ok_or_else(|| {
anyhow!("Either the --location or the --primary-location argument is required")
})?;
serve(
if let Some(secondary_location) = secondary_location { if let Some(secondary_location) = secondary_location {
Store::open_persistent_secondary(primary_location, secondary_location) Store::open_persistent_secondary(primary_location, secondary_location)
} else { } else {
@ -239,23 +231,24 @@ pub fn main() -> anyhow::Result<()> {
}?, }?,
bind, bind,
true, true,
), )
Command::Backup { }
location, Command::Backup { destination } => {
destination, let store = Store::open_read_only(
} => { matches
let store = Store::open_read_only(location)?; .location
.ok_or_else(|| anyhow!("The --location argument is required"))?,
)?;
store.backup(destination)?; store.backup(destination)?;
Ok(()) Ok(())
} }
Command::Load { Command::Load {
file, file,
location,
lenient, lenient,
format, format,
graph, graph,
} => { } => {
let store = if let Some(location) = location { let store = if let Some(location) = matches.location {
Store::open(location) Store::open(location)
} else { } else {
eprintln!("Warning: opening an in-memory store. It will not be possible to read the written data."); eprintln!("Warning: opening an in-memory store. It will not be possible to read the written data.");
@ -379,12 +372,15 @@ pub fn main() -> anyhow::Result<()> {
} }
} }
Command::Dump { Command::Dump {
location,
file, file,
format, format,
graph, graph,
} => { } => {
let store = Store::open_read_only(location)?; let store = Store::open_read_only(
matches
.location
.ok_or_else(|| anyhow!("The --location argument is required"))?,
)?;
let format = if let Some(format) = format { let format = if let Some(format) = format {
GraphOrDatasetFormat::from_str(&format)? GraphOrDatasetFormat::from_str(&format)?
} else if let Some(file) = &file { } else if let Some(file) = &file {
@ -417,7 +413,6 @@ pub fn main() -> anyhow::Result<()> {
} }
} }
Command::Query { Command::Query {
location,
query, query,
query_file, query_file,
query_base, query_base,
@ -437,7 +432,11 @@ pub fn main() -> anyhow::Result<()> {
query query
}; };
let query = Query::parse(&query, query_base.as_deref())?; let query = Query::parse(&query, query_base.as_deref())?;
let store = Store::open_read_only(location)?; let store = Store::open_read_only(
matches
.location
.ok_or_else(|| anyhow!("The --location argument is required"))?,
)?;
match store.query(query)? { match store.query(query)? {
QueryResults::Solutions(solutions) => { QueryResults::Solutions(solutions) => {
let format = if let Some(name) = results_format { let format = if let Some(name) = results_format {
@ -541,7 +540,6 @@ pub fn main() -> anyhow::Result<()> {
Ok(()) Ok(())
} }
Command::Update { Command::Update {
location,
update, update,
update_file, update_file,
update_base, update_base,
@ -559,7 +557,11 @@ pub fn main() -> anyhow::Result<()> {
update update
}; };
let update = Update::parse(&update, update_base.as_deref())?; let update = Update::parse(&update, update_base.as_deref())?;
let store = Store::open(location)?; let store = Store::open(
matches
.location
.ok_or_else(|| anyhow!("The --location argument is required"))?,
)?;
store.update(update)?; store.update(update)?;
Ok(()) Ok(())
} }
@ -1635,9 +1637,9 @@ mod tests {
input_file input_file
.write_str("<http://example.com/s> <http://example.com/p> <http://example.com/o> .")?; .write_str("<http://example.com/s> <http://example.com/p> <http://example.com/o> .")?;
cli_command()? cli_command()?
.arg("load")
.arg("--location") .arg("--location")
.arg(store_dir.path()) .arg(store_dir.path())
.arg("load")
.arg("--file") .arg("--file")
.arg(input_file.path()) .arg(input_file.path())
.assert() .assert()

Loading…
Cancel
Save