feat(control): add trigger command
This commit is contained in:
parent
9ebbf7d038
commit
308efc1eba
7 changed files with 190 additions and 17 deletions
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "sonic-channel"
|
name = "sonic-channel"
|
||||||
version = "0.2.2"
|
version = "0.3.0"
|
||||||
authors = ["Dmitriy Pleshevskiy <dmitriy@ideascup.me>"]
|
authors = ["Dmitriy Pleshevskiy <dmitriy@ideascup.me>"]
|
||||||
description = "Rust client for sonic search backend"
|
description = "Rust client for sonic search backend"
|
||||||
categories = ["api-bindings"]
|
categories = ["api-bindings"]
|
||||||
|
|
27
README.md
27
README.md
|
@ -7,18 +7,18 @@ We recommend you start with the [documentation].
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
Add `sonic-channel = { version = "0.2" }` as a dependency in `Cargo.toml`.
|
Add `sonic-channel = { version = "0.3" }` as a dependency in `Cargo.toml`.
|
||||||
|
|
||||||
`Cargo.toml` example:
|
`Cargo.toml` example:
|
||||||
|
|
||||||
```toml
|
```toml
|
||||||
[package]
|
[package]
|
||||||
name = "my-crate"
|
name = "my-crate"
|
||||||
version = "0.2.0"
|
version = "0.1.0"
|
||||||
authors = ["Me <user@rust-lang.org>"]
|
authors = ["Me <user@rust-lang.org>"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
sonic-channel = { version = "0.2" }
|
sonic-channel = { version = "0.3" }
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
@ -68,6 +68,27 @@ fn main() -> result::Result<()> {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Control channel
|
||||||
|
|
||||||
|
Note: This example requires enabling the `control` feature.
|
||||||
|
|
||||||
|
```rust
|
||||||
|
use sonic_channel::*;
|
||||||
|
|
||||||
|
fn main() -> result::Result<()> {
|
||||||
|
let mut channel = SonicChannel::connect_with_start(
|
||||||
|
ChannelMode::Control,
|
||||||
|
"localhost:1491",
|
||||||
|
"SecretPassword",
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let result = channel.consolidate()?;
|
||||||
|
assert_eq!(result, true);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
## Available features
|
## Available features
|
||||||
|
|
||||||
|
|
103
src/channel.rs
103
src/channel.rs
|
@ -519,13 +519,13 @@ impl SonicChannel {
|
||||||
```rust,no_run
|
```rust,no_run
|
||||||
# use sonic_channel::*;
|
# use sonic_channel::*;
|
||||||
# fn main() -> result::Result<()> {
|
# fn main() -> result::Result<()> {
|
||||||
let ingest_channel = SonicChannel::connect_with_start(
|
let search_channel = SonicChannel::connect_with_start(
|
||||||
ChannelMode::Search,
|
ChannelMode::Search,
|
||||||
"localhost:1491",
|
"localhost:1491",
|
||||||
"SecretPassword",
|
"SecretPassword",
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let result = ingest_channel.query("search", "default", "Beef")?;
|
let result = search_channel.query("search", "default", "Beef")?;
|
||||||
dbg!(result);
|
dbg!(result);
|
||||||
# Ok(())
|
# Ok(())
|
||||||
# }
|
# }
|
||||||
|
@ -547,13 +547,13 @@ impl SonicChannel {
|
||||||
```rust,no_run
|
```rust,no_run
|
||||||
# use sonic_channel::*;
|
# use sonic_channel::*;
|
||||||
# fn main() -> result::Result<()> {
|
# fn main() -> result::Result<()> {
|
||||||
let ingest_channel = SonicChannel::connect_with_start(
|
let search_channel = SonicChannel::connect_with_start(
|
||||||
ChannelMode::Search,
|
ChannelMode::Search,
|
||||||
"localhost:1491",
|
"localhost:1491",
|
||||||
"SecretPassword",
|
"SecretPassword",
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let result = ingest_channel.query_with_limit(
|
let result = search_channel.query_with_limit(
|
||||||
"search",
|
"search",
|
||||||
"default",
|
"default",
|
||||||
"Beef",
|
"Beef",
|
||||||
|
@ -581,13 +581,13 @@ impl SonicChannel {
|
||||||
```rust,no_run
|
```rust,no_run
|
||||||
# use sonic_channel::*;
|
# use sonic_channel::*;
|
||||||
# fn main() -> result::Result<()> {
|
# fn main() -> result::Result<()> {
|
||||||
let ingest_channel = SonicChannel::connect_with_start(
|
let search_channel = SonicChannel::connect_with_start(
|
||||||
ChannelMode::Search,
|
ChannelMode::Search,
|
||||||
"localhost:1491",
|
"localhost:1491",
|
||||||
"SecretPassword",
|
"SecretPassword",
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let result = ingest_channel.query_with_limit_and_offset(
|
let result = search_channel.query_with_limit_and_offset(
|
||||||
"search",
|
"search",
|
||||||
"default",
|
"default",
|
||||||
"Beef",
|
"Beef",
|
||||||
|
@ -616,13 +616,13 @@ impl SonicChannel {
|
||||||
```rust,no_run
|
```rust,no_run
|
||||||
# use sonic_channel::*;
|
# use sonic_channel::*;
|
||||||
# fn main() -> result::Result<()> {
|
# fn main() -> result::Result<()> {
|
||||||
let ingest_channel = SonicChannel::connect_with_start(
|
let search_channel = SonicChannel::connect_with_start(
|
||||||
ChannelMode::Search,
|
ChannelMode::Search,
|
||||||
"localhost:1491",
|
"localhost:1491",
|
||||||
"SecretPassword",
|
"SecretPassword",
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let result = ingest_channel.suggest("search", "default", "Beef")?;
|
let result = search_channel.suggest("search", "default", "Beef")?;
|
||||||
dbg!(result);
|
dbg!(result);
|
||||||
# Ok(())
|
# Ok(())
|
||||||
# }
|
# }
|
||||||
|
@ -634,7 +634,6 @@ impl SonicChannel {
|
||||||
word: &'a str,
|
word: &'a str,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
#[doc=r#"
|
#[doc=r#"
|
||||||
Suggest auto-completes words with limit.
|
Suggest auto-completes words with limit.
|
||||||
|
|
||||||
|
@ -644,13 +643,13 @@ impl SonicChannel {
|
||||||
```rust,no_run
|
```rust,no_run
|
||||||
# use sonic_channel::*;
|
# use sonic_channel::*;
|
||||||
# fn main() -> result::Result<()> {
|
# fn main() -> result::Result<()> {
|
||||||
let ingest_channel = SonicChannel::connect_with_start(
|
let search_channel = SonicChannel::connect_with_start(
|
||||||
ChannelMode::Search,
|
ChannelMode::Search,
|
||||||
"localhost:1491",
|
"localhost:1491",
|
||||||
"SecretPassword",
|
"SecretPassword",
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let result = ingest_channel.suggest_with_limit("search", "default", "Beef", 5)?;
|
let result = search_channel.suggest_with_limit("search", "default", "Beef", 5)?;
|
||||||
dbg!(result);
|
dbg!(result);
|
||||||
# Ok(())
|
# Ok(())
|
||||||
# }
|
# }
|
||||||
|
@ -665,5 +664,85 @@ impl SonicChannel {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "control")]
|
#[cfg(feature = "control")]
|
||||||
init_commands! {}
|
init_commands! {
|
||||||
|
#[doc=r#"
|
||||||
|
Consolidate indexed search data instead of waiting for the next automated
|
||||||
|
consolidation tick.
|
||||||
|
|
||||||
|
Note: This method requires enabling the `control` feature and start
|
||||||
|
connection in Control mode.
|
||||||
|
|
||||||
|
```rust,no_run
|
||||||
|
# use sonic_channel::*;
|
||||||
|
# fn main() -> result::Result<()> {
|
||||||
|
let control_channel = SonicChannel::connect_with_start(
|
||||||
|
ChannelMode::Control,
|
||||||
|
"localhost:1491",
|
||||||
|
"SecretPassword",
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let result = control_channel.consolidate()?;
|
||||||
|
assert_eq!(result, true);
|
||||||
|
# Ok(())
|
||||||
|
# }
|
||||||
|
```
|
||||||
|
"#]
|
||||||
|
use TriggerCommand for fn consolidate();
|
||||||
|
|
||||||
|
#[doc=r#"
|
||||||
|
Backup KV + FST to <path>/<BACKUP_{KV/FST}_PATH>
|
||||||
|
See [sonic backend source code](https://github.com/valeriansaliou/sonic/blob/master/src/channel/command.rs#L808)
|
||||||
|
for more information.
|
||||||
|
|
||||||
|
Note: This method requires enabling the `control` feature and start
|
||||||
|
connection in Control mode.
|
||||||
|
|
||||||
|
```rust,no_run
|
||||||
|
# use sonic_channel::*;
|
||||||
|
# fn main() -> result::Result<()> {
|
||||||
|
let control_channel = SonicChannel::connect_with_start(
|
||||||
|
ChannelMode::Control,
|
||||||
|
"localhost:1491",
|
||||||
|
"SecretPassword",
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let result = control_channel.backup("2020-08-07T23-48")?;
|
||||||
|
assert_eq!(result, true);
|
||||||
|
# Ok(())
|
||||||
|
# }
|
||||||
|
```
|
||||||
|
"#]
|
||||||
|
use TriggerCommand for fn backup<'a>(
|
||||||
|
// It's not action, but my macro cannot support alias for custom argument.
|
||||||
|
// TODO: Add alias to macro and rename argument of this function.
|
||||||
|
action: &'a str => TriggerAction::Backup(action),
|
||||||
|
);
|
||||||
|
|
||||||
|
#[doc=r#"
|
||||||
|
Restore KV + FST from <path> if you already have backup with the same name.
|
||||||
|
|
||||||
|
Note: This method requires enabling the `control` feature and start
|
||||||
|
connection in Control mode.
|
||||||
|
|
||||||
|
```rust,no_run
|
||||||
|
# use sonic_channel::*;
|
||||||
|
# fn main() -> result::Result<()> {
|
||||||
|
let control_channel = SonicChannel::connect_with_start(
|
||||||
|
ChannelMode::Control,
|
||||||
|
"localhost:1491",
|
||||||
|
"SecretPassword",
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let result = control_channel.restore("2020-08-07T23-48")?;
|
||||||
|
assert_eq!(result, true);
|
||||||
|
# Ok(())
|
||||||
|
# }
|
||||||
|
```
|
||||||
|
"#]
|
||||||
|
use TriggerCommand for fn restore<'a>(
|
||||||
|
// It's not action, but my macro cannot support alias for custom argument.
|
||||||
|
// TODO: Add alias to macro and rename argument of this function.
|
||||||
|
action: &'a str => TriggerAction::Restore(action),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
use super::StreamCommand;
|
use super::StreamCommand;
|
||||||
use crate::result::*;
|
use crate::result::*;
|
||||||
|
|
||||||
#[doc(hidden)]
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct CountCommand<'a> {
|
pub struct CountCommand<'a> {
|
||||||
pub collection: &'a str,
|
pub collection: &'a str,
|
||||||
|
|
|
@ -17,6 +17,9 @@ mod query;
|
||||||
#[cfg(feature = "search")]
|
#[cfg(feature = "search")]
|
||||||
mod suggest;
|
mod suggest;
|
||||||
|
|
||||||
|
#[cfg(feature = "control")]
|
||||||
|
mod trigger;
|
||||||
|
|
||||||
pub(crate) use quit::QuitCommand;
|
pub(crate) use quit::QuitCommand;
|
||||||
pub(crate) use start::StartCommand;
|
pub(crate) use start::StartCommand;
|
||||||
|
|
||||||
|
@ -36,6 +39,9 @@ pub(crate) use query::QueryCommand;
|
||||||
#[cfg(feature = "search")]
|
#[cfg(feature = "search")]
|
||||||
pub(crate) use suggest::SuggestCommand;
|
pub(crate) use suggest::SuggestCommand;
|
||||||
|
|
||||||
|
#[cfg(feature = "control")]
|
||||||
|
pub(crate) use trigger::{TriggerCommand, TriggerAction};
|
||||||
|
|
||||||
use crate::result::Result;
|
use crate::result::Result;
|
||||||
|
|
||||||
pub trait StreamCommand {
|
pub trait StreamCommand {
|
||||||
|
|
47
src/commands/trigger.rs
Normal file
47
src/commands/trigger.rs
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
use super::StreamCommand;
|
||||||
|
use crate::result::*;
|
||||||
|
use std::fmt;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum TriggerAction<'a> {
|
||||||
|
Consolidate,
|
||||||
|
Backup(&'a str),
|
||||||
|
Restore(&'a str),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for TriggerAction<'_> {
|
||||||
|
fn default() -> Self {
|
||||||
|
TriggerAction::Consolidate
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for TriggerAction<'_> {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> std::result::Result<(), fmt::Error> {
|
||||||
|
match self {
|
||||||
|
TriggerAction::Consolidate => write!(f, "consolidate"),
|
||||||
|
TriggerAction::Backup(data) => write!(f, "backup {}", data),
|
||||||
|
TriggerAction::Restore(data) => write!(f, "restore {}", data),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
pub struct TriggerCommand<'a> {
|
||||||
|
pub action: TriggerAction<'a>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl StreamCommand for TriggerCommand<'_> {
|
||||||
|
type Response = bool;
|
||||||
|
|
||||||
|
fn message(&self) -> String {
|
||||||
|
format!("TRIGGER {}\r\n", self.action)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn receive(&self, message: String) -> Result<Self::Response> {
|
||||||
|
if message == "OK\r\n" {
|
||||||
|
Ok(true)
|
||||||
|
} else {
|
||||||
|
Err(Error::new(ErrorKind::WrongSonicResponse))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
21
src/lib.rs
21
src/lib.rs
|
@ -48,6 +48,27 @@
|
||||||
//! }
|
//! }
|
||||||
//! ```
|
//! ```
|
||||||
//!
|
//!
|
||||||
|
//! ### Control channel
|
||||||
|
//!
|
||||||
|
//! Note: This example requires enabling the `control` feature.
|
||||||
|
//!
|
||||||
|
//! ```rust,no_run
|
||||||
|
//! use sonic_channel::*;
|
||||||
|
//!
|
||||||
|
//! fn main() -> result::Result<()> {
|
||||||
|
//! let mut channel = SonicChannel::connect_with_start(
|
||||||
|
//! ChannelMode::Control,
|
||||||
|
//! "localhost:1491",
|
||||||
|
//! "SecretPassword",
|
||||||
|
//! )?;
|
||||||
|
//!
|
||||||
|
//! let result = channel.consolidate()?;
|
||||||
|
//! assert_eq!(result, true);
|
||||||
|
//!
|
||||||
|
//! Ok(())
|
||||||
|
//! }
|
||||||
|
//! ```
|
||||||
|
//!
|
||||||
//! [sonic]: https://github.com/valeriansaliou/sonic
|
//! [sonic]: https://github.com/valeriansaliou/sonic
|
||||||
|
|
||||||
// Rustc lints.
|
// Rustc lints.
|
||||||
|
|
Loading…
Reference in a new issue