feat: add count method
This commit is contained in:
parent
85ddd8fb4e
commit
9ebbf7d038
11 changed files with 156 additions and 20 deletions
|
@ -428,6 +428,84 @@ impl SonicChannel {
|
||||||
bucket: &'a str => Some(bucket),
|
bucket: &'a str => Some(bucket),
|
||||||
object: &'a str => Some(object),
|
object: &'a str => Some(object),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
#[doc=r#"
|
||||||
|
Bucket count in indexed search data of your collection.
|
||||||
|
|
||||||
|
Note: This method requires enabling the `ingest` feature and start
|
||||||
|
connection in Ingest mode.
|
||||||
|
|
||||||
|
```rust,no_run
|
||||||
|
# use sonic_channel::*;
|
||||||
|
# fn main() -> result::Result<()> {
|
||||||
|
let ingest_channel = SonicChannel::connect_with_start(
|
||||||
|
ChannelMode::Ingest,
|
||||||
|
"localhost:1491",
|
||||||
|
"SecretPassword",
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let bucket_count = ingest_channel.bucket_count("search")?;
|
||||||
|
dbg!(bucket_count);
|
||||||
|
# Ok(())
|
||||||
|
# }
|
||||||
|
```
|
||||||
|
"#]
|
||||||
|
use CountCommand for fn bucket_count<'a>(
|
||||||
|
collection: &'a str,
|
||||||
|
);
|
||||||
|
|
||||||
|
#[doc=r#"
|
||||||
|
Object count of bucket in indexed search data.
|
||||||
|
|
||||||
|
Note: This method requires enabling the `ingest` feature and start
|
||||||
|
connection in Ingest mode.
|
||||||
|
|
||||||
|
```rust,no_run
|
||||||
|
# use sonic_channel::*;
|
||||||
|
# fn main() -> result::Result<()> {
|
||||||
|
let ingest_channel = SonicChannel::connect_with_start(
|
||||||
|
ChannelMode::Ingest,
|
||||||
|
"localhost:1491",
|
||||||
|
"SecretPassword",
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let object_count = ingest_channel.object_count("search", "default")?;
|
||||||
|
dbg!(object_count);
|
||||||
|
# Ok(())
|
||||||
|
# }
|
||||||
|
```
|
||||||
|
"#]
|
||||||
|
use CountCommand for fn object_count<'a>(
|
||||||
|
collection: &'a str,
|
||||||
|
bucket: &'a str => Some(bucket),
|
||||||
|
);
|
||||||
|
|
||||||
|
#[doc=r#"
|
||||||
|
Object word count in indexed bucket search data.
|
||||||
|
|
||||||
|
Note: This method requires enabling the `ingest` feature and start
|
||||||
|
connection in Ingest mode.
|
||||||
|
|
||||||
|
```rust,no_run
|
||||||
|
# use sonic_channel::*;
|
||||||
|
# fn main() -> result::Result<()> {
|
||||||
|
let ingest_channel = SonicChannel::connect_with_start(
|
||||||
|
ChannelMode::Ingest,
|
||||||
|
"localhost:1491",
|
||||||
|
"SecretPassword",
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let word_count = ingest_channel.word_count("search", "default", "recipe:296")?;
|
||||||
|
dbg!(word_count);
|
||||||
|
# Ok(())
|
||||||
|
# }
|
||||||
|
```
|
||||||
|
"#]
|
||||||
|
use CountCommand for fn word_count<'a>(
|
||||||
|
collection: &'a str,
|
||||||
|
bucket: &'a str => Some(bucket),
|
||||||
|
object: &'a str => Some(object),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "search")]
|
#[cfg(feature = "search")]
|
||||||
|
@ -572,7 +650,7 @@ impl SonicChannel {
|
||||||
"SecretPassword",
|
"SecretPassword",
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let result = ingest_channel.suggest("search", "default", "Beef", 5)?;
|
let result = ingest_channel.suggest_with_limit("search", "default", "Beef", 5)?;
|
||||||
dbg!(result);
|
dbg!(result);
|
||||||
# Ok(())
|
# Ok(())
|
||||||
# }
|
# }
|
||||||
|
|
40
src/commands/count.rs
Normal file
40
src/commands/count.rs
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
use super::StreamCommand;
|
||||||
|
use crate::result::*;
|
||||||
|
|
||||||
|
#[doc(hidden)]
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
pub struct CountCommand<'a> {
|
||||||
|
pub collection: &'a str,
|
||||||
|
pub bucket: Option<&'a str>,
|
||||||
|
pub object: Option<&'a str>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl StreamCommand for CountCommand<'_> {
|
||||||
|
type Response = usize;
|
||||||
|
|
||||||
|
fn message(&self) -> String {
|
||||||
|
let mut message = format!("COUNT {}", self.collection);
|
||||||
|
if let Some(bucket) = self.bucket {
|
||||||
|
message.push_str(&format!(" {}", bucket));
|
||||||
|
|
||||||
|
if let Some(object) = self.object {
|
||||||
|
message.push_str(&format!(" {}", object));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
message.push_str("\r\n");
|
||||||
|
message
|
||||||
|
}
|
||||||
|
|
||||||
|
fn receive(&self, message: String) -> Result<Self::Response> {
|
||||||
|
if message.starts_with("RESULT ") {
|
||||||
|
let count = message.split_whitespace().last().unwrap_or_default();
|
||||||
|
count.parse().map_err(|_| {
|
||||||
|
Error::new(ErrorKind::QueryResponseError(
|
||||||
|
"Cannot parse count of count method response to usize",
|
||||||
|
))
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
Err(Error::new(ErrorKind::WrongSonicResponse))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -33,9 +33,7 @@ impl StreamCommand for FlushCommand<'_> {
|
||||||
))
|
))
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
Err(Error::new(ErrorKind::QueryResponseError(
|
Err(Error::new(ErrorKind::WrongSonicResponse))
|
||||||
"Sonic response are wrong. Please write issue to github.",
|
|
||||||
)))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,8 @@ mod start;
|
||||||
|
|
||||||
mod ping;
|
mod ping;
|
||||||
|
|
||||||
|
#[cfg(feature = "ingest")]
|
||||||
|
mod count;
|
||||||
#[cfg(feature = "ingest")]
|
#[cfg(feature = "ingest")]
|
||||||
mod flush;
|
mod flush;
|
||||||
#[cfg(feature = "ingest")]
|
#[cfg(feature = "ingest")]
|
||||||
|
@ -20,6 +22,8 @@ pub(crate) use start::StartCommand;
|
||||||
|
|
||||||
pub(crate) use ping::PingCommand;
|
pub(crate) use ping::PingCommand;
|
||||||
|
|
||||||
|
#[cfg(feature = "ingest")]
|
||||||
|
pub(crate) use count::CountCommand;
|
||||||
#[cfg(feature = "ingest")]
|
#[cfg(feature = "ingest")]
|
||||||
pub(crate) use flush::FlushCommand;
|
pub(crate) use flush::FlushCommand;
|
||||||
#[cfg(feature = "ingest")]
|
#[cfg(feature = "ingest")]
|
||||||
|
|
|
@ -13,6 +13,10 @@ impl StreamCommand for PingCommand {
|
||||||
|
|
||||||
fn receive(&self, message: String) -> Result<Self::Response> {
|
fn receive(&self, message: String) -> Result<Self::Response> {
|
||||||
dbg!(&message);
|
dbg!(&message);
|
||||||
Ok(message == "PONG\r\n")
|
if message == "PONG\r\n" {
|
||||||
|
Ok(true)
|
||||||
|
} else {
|
||||||
|
Err(Error::new(ErrorKind::WrongSonicResponse))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use super::StreamCommand;
|
use super::StreamCommand;
|
||||||
use crate::result::{Error, ErrorKind, Result};
|
use crate::result::*;
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct PopCommand<'a> {
|
pub struct PopCommand<'a> {
|
||||||
|
@ -31,7 +31,7 @@ impl StreamCommand for PopCommand<'_> {
|
||||||
)))
|
)))
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
Err(Error::new(ErrorKind::QueryResponseError("Cannot parse result")))
|
Err(Error::new(ErrorKind::WrongSonicResponse))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use super::StreamCommand;
|
use super::StreamCommand;
|
||||||
use crate::result::Result;
|
use crate::result::*;
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct PushCommand<'a> {
|
pub struct PushCommand<'a> {
|
||||||
|
@ -27,6 +27,11 @@ impl StreamCommand for PushCommand<'_> {
|
||||||
|
|
||||||
fn receive(&self, message: String) -> Result<Self::Response> {
|
fn receive(&self, message: String) -> Result<Self::Response> {
|
||||||
dbg!(&message);
|
dbg!(&message);
|
||||||
Ok(message == "OK\r\n")
|
|
||||||
|
if message == "OK\r\n" {
|
||||||
|
Ok(true)
|
||||||
|
} else {
|
||||||
|
Err(Error::new(ErrorKind::WrongSonicResponse))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,9 +44,7 @@ impl StreamCommand for QueryCommand<'_> {
|
||||||
dbg!(&message);
|
dbg!(&message);
|
||||||
|
|
||||||
match RE.captures(&message) {
|
match RE.captures(&message) {
|
||||||
None => Err(Error::new(ErrorKind::QueryResponseError(
|
None => Err(Error::new(ErrorKind::WrongSonicResponse)),
|
||||||
"Sonic response are wrong. Please write issue to github.",
|
|
||||||
))),
|
|
||||||
Some(caps) => {
|
Some(caps) => {
|
||||||
if &caps["pending_query_id"] != &caps["event_query_id"] {
|
if &caps["pending_query_id"] != &caps["event_query_id"] {
|
||||||
Err(Error::new(ErrorKind::QueryResponseError(
|
Err(Error::new(ErrorKind::QueryResponseError(
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use super::StreamCommand;
|
use super::StreamCommand;
|
||||||
use crate::result::Result;
|
use crate::result::*;
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct QuitCommand;
|
pub struct QuitCommand;
|
||||||
|
@ -13,6 +13,10 @@ impl StreamCommand for QuitCommand {
|
||||||
|
|
||||||
fn receive(&self, message: String) -> Result<Self::Response> {
|
fn receive(&self, message: String) -> Result<Self::Response> {
|
||||||
dbg!(&message);
|
dbg!(&message);
|
||||||
Ok(message.starts_with("ENDED "))
|
if message.starts_with("ENDED ") {
|
||||||
|
Ok(true)
|
||||||
|
} else {
|
||||||
|
Err(Error::new(ErrorKind::WrongSonicResponse))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,9 +40,7 @@ impl StreamCommand for SuggestCommand<'_> {
|
||||||
dbg!(&message);
|
dbg!(&message);
|
||||||
|
|
||||||
match RE.captures(&message) {
|
match RE.captures(&message) {
|
||||||
None => Err(Error::new(ErrorKind::QueryResponseError(
|
None => Err(Error::new(ErrorKind::WrongSonicResponse)),
|
||||||
"Sonic response are wrong. Please write issue to github.",
|
|
||||||
))),
|
|
||||||
Some(caps) => {
|
Some(caps) => {
|
||||||
if &caps["pending_suggest_id"] != &caps["event_suggest_id"] {
|
if &caps["pending_suggest_id"] != &caps["event_suggest_id"] {
|
||||||
Err(Error::new(ErrorKind::QueryResponseError(
|
Err(Error::new(ErrorKind::QueryResponseError(
|
||||||
|
|
|
@ -4,7 +4,7 @@ use std::fmt;
|
||||||
/// Sugar if you expect only sonic-channel error type in result
|
/// Sugar if you expect only sonic-channel error type in result
|
||||||
pub type Result<T> = std::result::Result<T, Error>;
|
pub type Result<T> = std::result::Result<T, Error>;
|
||||||
|
|
||||||
/// Wrap for sonic channel error kind. This type has std::error::Error
|
/// Wrap for sonic channel error kind. This type has std::error::Error
|
||||||
/// implementation and you can use boxed trait for catch other errors
|
/// implementation and you can use boxed trait for catch other errors
|
||||||
/// like this.
|
/// like this.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -16,10 +16,10 @@ impl StdError for Error {}
|
||||||
|
|
||||||
impl Error {
|
impl Error {
|
||||||
/// Creates new Error with sonic channel error kind
|
/// Creates new Error with sonic channel error kind
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// use sonic_channel::result::*;
|
/// use sonic_channel::result::*;
|
||||||
///
|
///
|
||||||
/// let err = Error::new(ErrorKind::ConnectToServer);
|
/// let err = Error::new(ErrorKind::ConnectToServer);
|
||||||
/// ```
|
/// ```
|
||||||
pub fn new(kind: ErrorKind) -> Self {
|
pub fn new(kind: ErrorKind) -> Self {
|
||||||
|
@ -47,6 +47,10 @@ pub enum ErrorKind {
|
||||||
|
|
||||||
/// Error in query response with additional message.
|
/// Error in query response with additional message.
|
||||||
QueryResponseError(&'static str),
|
QueryResponseError(&'static str),
|
||||||
|
|
||||||
|
/// Response from sonic server are wrong! Actually it may happen if you use
|
||||||
|
/// unsupported sonic backend version. Please write issue to the github repo.
|
||||||
|
WrongSonicResponse,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for Error {
|
impl fmt::Display for Error {
|
||||||
|
@ -60,6 +64,9 @@ impl fmt::Display for Error {
|
||||||
ErrorKind::QueryResponseError(message) => {
|
ErrorKind::QueryResponseError(message) => {
|
||||||
write!(f, "Error in query response: {}", message)
|
write!(f, "Error in query response: {}", message)
|
||||||
}
|
}
|
||||||
|
ErrorKind::WrongSonicResponse => {
|
||||||
|
write!(f, "Sonic response are wrong. Please write issue to github.")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue