feat: add count method

This commit is contained in:
Dmitriy Pleshevskiy 2020-08-07 02:03:11 +03:00
parent 85ddd8fb4e
commit 9ebbf7d038
11 changed files with 156 additions and 20 deletions

View file

@ -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
View 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))
}
}
}

View file

@ -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.",
)))
} }
} }
} }

View file

@ -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")]

View file

@ -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))
}
} }
} }

View file

@ -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))
} }
} }
} }

View file

@ -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))
}
} }
} }

View file

@ -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(

View file

@ -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))
}
} }
} }

View file

@ -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(

View file

@ -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.")
}
} }
} }
} }