Server: removes the "location" argument to relevant commands

pull/602/head
Tpt 1 year ago committed by Thomas Tanon
parent f586cc048f
commit 788450932a
  1. 6
      server/README.md
  2. 116
      server/src/main.rs

@ -44,7 +44,7 @@ It will create a fat binary in `target/release/oxigraph_server`.
## Usage ## Usage
Run `oxigraph_server --location my_data_storage_directory serve` to start the server where `my_data_storage_directory` is the directory where you want Oxigraph data to be stored. It listens by default on `localhost:7878`. Run `oxigraph_server serve --location my_data_storage_directory` to start the server where `my_data_storage_directory` is the directory where you want Oxigraph data to be stored. It listens by default on `localhost:7878`.
The server provides an HTML UI, based on [YASGUI](https://yasgui.triply.cc), with a form to execute SPARQL requests. The server provides an HTML UI, based on [YASGUI](https://yasgui.triply.cc), with a form to execute SPARQL requests.
@ -81,7 +81,7 @@ It provides the following REST actions:
Use `oxigraph_server --help` to see the possible options when starting the server. Use `oxigraph_server --help` to see the possible options when starting the server.
It is also possible to load RDF data offline using bulk loading: It is also possible to load RDF data offline using bulk loading:
`oxigraph_server --location my_data_storage_directory load --file my_file.nq` `oxigraph_server load --location my_data_storage_directory --file my_file.nq`
## Using a Docker image ## Using a Docker image
@ -93,7 +93,7 @@ docker run --rm ghcr.io/oxigraph/oxigraph --help
### Run the Webserver ### Run the Webserver
Expose the server on port `7878` of the host machine, and save data on the local `./data` folder Expose the server on port `7878` of the host machine, and save data on the local `./data` folder
```sh ```sh
docker run --rm -v $PWD/data:/data -p 7878:7878 ghcr.io/oxigraph/oxigraph --location /data serve --bind 0.0.0.0:7878 docker run --rm -v $PWD/data:/data -p 7878:7878 ghcr.io/oxigraph/oxigraph serve --location /data --bind 0.0.0.0:7878
``` ```
You can then access it from your machine on port `7878`: You can then access it from your machine on port `7878`:

@ -41,11 +41,6 @@ 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,
} }
@ -54,6 +49,11 @@ 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 should be persisted.
///
/// If not present. An in-memory storage will be used.
#[arg(short, long)]
location: Option<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,
@ -67,6 +67,9 @@ 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 Oxigraph data 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,
@ -83,8 +86,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, conflicts_with = "location")] #[arg(long)]
primary_location: Option<PathBuf>, primary_location: 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.
@ -109,12 +112,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 Oxigraph data are persisted.
#[arg(short, long)]
location: PathBuf,
/// Directory in which the backup will be written. /// Directory in which the backup will be written.
#[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 Oxigraph data are persisted.
#[arg(short, long)]
location: PathBuf,
/// 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.
@ -145,6 +154,9 @@ enum Command {
}, },
/// Dump the store content into a file. /// Dump the store content into a file.
Dump { Dump {
/// Directory in which Oxigraph data 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.
@ -165,6 +177,9 @@ enum Command {
}, },
/// Executes a SPARQL query against the store. /// Executes a SPARQL query against the store.
Query { Query {
/// Directory in which Oxigraph data 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.
@ -210,6 +225,9 @@ enum Command {
}, },
/// Executes a SPARQL update against the store. /// Executes a SPARQL update against the store.
Update { Update {
/// Directory in which Oxigraph data 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.
@ -228,7 +246,11 @@ enum Command {
/// ///
/// Done by default in the background when serving requests. /// Done by default in the background when serving requests.
/// It is likely to not be useful in most of cases except if you provide a read-only SPARQL endpoint under heavy load. /// It is likely to not be useful in most of cases except if you provide a read-only SPARQL endpoint under heavy load.
Optimize {}, Optimize {
/// Directory in which Oxigraph data are persisted.
#[arg(short, long)]
location: PathBuf,
},
/// Converts a RDF serialization from one format to an other. /// Converts a RDF serialization from one format to an other.
Convert { Convert {
/// File to convert from. /// File to convert from.
@ -280,8 +302,12 @@ 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 { bind, cors } => serve( Command::Serve {
if let Some(location) = matches.location { location,
bind,
cors,
} => serve(
if let Some(location) = location {
Store::open(location) Store::open(location)
} else { } else {
Store::new() Store::new()
@ -290,26 +316,17 @@ pub fn main() -> anyhow::Result<()> {
false, false,
cors, cors,
), ),
Command::ServeReadOnly { bind, cors } => serve( Command::ServeReadOnly {
Store::open_read_only( location,
matches
.location
.ok_or_else(|| anyhow!("The --location argument is required"))?,
)?,
bind, bind,
true,
cors, cors,
), } => serve(Store::open_read_only(location)?, bind, true, cors),
Command::ServeSecondary { Command::ServeSecondary {
primary_location, primary_location,
secondary_location, secondary_location,
bind, bind,
cors, cors,
} => { } => 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 {
@ -318,30 +335,24 @@ pub fn main() -> anyhow::Result<()> {
bind, bind,
true, true,
cors, cors,
) ),
} Command::Backup {
Command::Backup { destination } => { location,
let store = Store::open_read_only( destination,
matches } => {
.location let store = Store::open_read_only(location)?;
.ok_or_else(|| anyhow!("The --location argument is required"))?,
)?;
store.backup(destination)?; store.backup(destination)?;
Ok(()) Ok(())
} }
Command::Load { Command::Load {
location,
file, file,
lenient, lenient,
format, format,
base, base,
graph, graph,
} => { } => {
let store = if let Some(location) = matches.location { let store = Store::open(location)?;
Store::open(location)
} else {
eprintln!("Warning: opening an in-memory store. It will not be possible to read the written data.");
Store::new()
}?;
let format = if let Some(format) = format { let format = if let Some(format) = format {
Some(rdf_format_from_name(&format)?) Some(rdf_format_from_name(&format)?)
} else { } else {
@ -462,15 +473,12 @@ pub fn main() -> anyhow::Result<()> {
} }
} }
Command::Dump { Command::Dump {
location,
file, file,
format, format,
graph, graph,
} => { } => {
let store = Store::open_read_only( let store = Store::open_read_only(location)?;
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 {
rdf_format_from_name(&format)? rdf_format_from_name(&format)?
} else if let Some(file) = &file { } else if let Some(file) = &file {
@ -502,6 +510,7 @@ pub fn main() -> anyhow::Result<()> {
Ok(()) Ok(())
} }
Command::Query { Command::Query {
location,
query, query,
query_file, query_file,
query_base, query_base,
@ -521,11 +530,7 @@ pub fn main() -> anyhow::Result<()> {
io::read_to_string(stdin().lock())? io::read_to_string(stdin().lock())?
}; };
let query = Query::parse(&query, query_base.as_deref())?; let query = Query::parse(&query, query_base.as_deref())?;
let store = Store::open_read_only( let store = Store::open_read_only(location)?;
matches
.location
.ok_or_else(|| anyhow!("The --location argument is required"))?,
)?;
let (results, explanation) = let (results, explanation) =
store.explain_query_opt(query, QueryOptions::default(), stats)?; store.explain_query_opt(query, QueryOptions::default(), stats)?;
let print_result = (|| { let print_result = (|| {
@ -648,6 +653,7 @@ pub fn main() -> anyhow::Result<()> {
print_result print_result
} }
Command::Update { Command::Update {
location,
update, update,
update_file, update_file,
update_base, update_base,
@ -662,21 +668,13 @@ pub fn main() -> anyhow::Result<()> {
io::read_to_string(stdin().lock())? io::read_to_string(stdin().lock())?
}; };
let update = Update::parse(&update, update_base.as_deref())?; let update = Update::parse(&update, update_base.as_deref())?;
let store = Store::open( let store = Store::open(location)?;
matches
.location
.ok_or_else(|| anyhow!("The --location argument is required"))?,
)?;
store.update(update)?; store.update(update)?;
store.flush()?; store.flush()?;
Ok(()) Ok(())
} }
Command::Optimize {} => { Command::Optimize { location } => {
let store = Store::open( let store = Store::open(location)?;
matches
.location
.ok_or_else(|| anyhow!("The --location argument is required"))?,
)?;
store.optimize()?; store.optimize()?;
Ok(()) Ok(())
} }
@ -1894,9 +1892,9 @@ mod tests {
let input_file = NamedTempFile::new("input.ttl")?; let input_file = NamedTempFile::new("input.ttl")?;
input_file.write_str("<s> <http://example.com/p> <http://example.com/o> .")?; input_file.write_str("<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())
.arg("--base") .arg("--base")

Loading…
Cancel
Save