commands/list: implement new list command to the search channel
Closes #22
This commit is contained in:
parent
65dfd3136c
commit
529105d340
8 changed files with 198 additions and 17 deletions
|
@ -2,7 +2,7 @@ version: '3'
|
|||
|
||||
services:
|
||||
sonic:
|
||||
image: valeriansaliou/sonic:v1.3.5
|
||||
image: valeriansaliou/sonic:v1.4.0
|
||||
ports:
|
||||
- 36999:1491
|
||||
volumes:
|
||||
|
|
42
flake.lock
42
flake.lock
|
@ -1,5 +1,20 @@
|
|||
{
|
||||
"nodes": {
|
||||
"flake-utils": {
|
||||
"locked": {
|
||||
"lastModified": 1659877975,
|
||||
"narHash": "sha256-zllb8aq3YO3h8B/U0/J1WBgAL8EX5yWf5pMj3G0NAmc=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "c0e246b9b83f637f4681389ecabcb2681b4f3af0",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1662096612,
|
||||
|
@ -18,22 +33,31 @@
|
|||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"flake-utils": "flake-utils",
|
||||
"nixpkgs": "nixpkgs",
|
||||
"utils": "utils"
|
||||
"sonic-server": "sonic-server"
|
||||
}
|
||||
},
|
||||
"utils": {
|
||||
"sonic-server": {
|
||||
"inputs": {
|
||||
"flake-utils": [
|
||||
"flake-utils"
|
||||
],
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1659877975,
|
||||
"narHash": "sha256-zllb8aq3YO3h8B/U0/J1WBgAL8EX5yWf5pMj3G0NAmc=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "c0e246b9b83f637f4681389ecabcb2681b4f3af0",
|
||||
"lastModified": 1666618211,
|
||||
"narHash": "sha256-kKeIM9dXUi8eYcvSomx8kqSqq9zmqMx4mE5wdpEZ6O8=",
|
||||
"owner": "pleshevskiy",
|
||||
"repo": "sonic",
|
||||
"rev": "e83de87ebd2e29b210c8cc6e7dfed5d2f14a0d24",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"owner": "pleshevskiy",
|
||||
"repo": "sonic",
|
||||
"type": "github"
|
||||
}
|
||||
}
|
||||
|
|
19
flake.nix
19
flake.nix
|
@ -1,17 +1,26 @@
|
|||
{
|
||||
inputs = {
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
|
||||
utils.url = "github:numtide/flake-utils";
|
||||
flake-utils.url = "github:numtide/flake-utils";
|
||||
|
||||
sonic-server = {
|
||||
url = "github:pleshevskiy/sonic";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
inputs.flake-utils.follows = "flake-utils";
|
||||
};
|
||||
};
|
||||
|
||||
outputs = { self, nixpkgs, utils }:
|
||||
utils.lib.eachDefaultSystem (system:
|
||||
outputs = inputs @ { self, nixpkgs, flake-utils, ... }:
|
||||
flake-utils.lib.eachDefaultSystem (system:
|
||||
let
|
||||
pkgs = import nixpkgs { inherit system; };
|
||||
pkgs = import nixpkgs {
|
||||
inherit system;
|
||||
overlays = [ inputs.sonic-server.overlays.default ];
|
||||
};
|
||||
in
|
||||
{
|
||||
devShell = pkgs.mkShell {
|
||||
packages = with pkgs; [ cargo rustc rustfmt clippy rust-analyzer ];
|
||||
packages = with pkgs; [ cargo rustc rustfmt clippy rust-analyzer sonic-server inetutils ];
|
||||
RUST_SRC_PATH = pkgs.rustPlatform.rustLibSrc;
|
||||
};
|
||||
});
|
||||
|
|
|
@ -130,4 +130,35 @@ impl SearchChannel {
|
|||
req: SuggestRequest,
|
||||
);
|
||||
);
|
||||
|
||||
init_command!(
|
||||
/// Enumerates all words in an index.
|
||||
///
|
||||
/// Note: This method requires enabling the `search` feature and start
|
||||
/// connection in Search mode.
|
||||
///
|
||||
/// ```rust,no_run
|
||||
/// # use sonic_channel::*;
|
||||
/// # fn main() -> result::Result<()> {
|
||||
/// let search_channel = SearchChannel::start(
|
||||
/// "localhost:1491",
|
||||
/// "SecretPassword",
|
||||
/// )?;
|
||||
///
|
||||
/// let result = search_channel.list(
|
||||
/// ListRequest::new(Dest::col("search"))
|
||||
/// )?;
|
||||
/// dbg!(result);
|
||||
///
|
||||
/// let result = search_channel.list(
|
||||
/// ListRequest::new(Dest::col("search")).limit(2)
|
||||
/// )?;
|
||||
/// dbg!(result);
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
use ListCommand for fn list(
|
||||
req: ListRequest,
|
||||
);
|
||||
);
|
||||
}
|
||||
|
|
|
@ -11,6 +11,8 @@ mod pop;
|
|||
#[cfg(feature = "ingest")]
|
||||
mod push;
|
||||
|
||||
#[cfg(feature = "search")]
|
||||
mod list;
|
||||
#[cfg(feature = "search")]
|
||||
mod query;
|
||||
#[cfg(feature = "search")]
|
||||
|
@ -29,9 +31,9 @@ pub(crate) use self::{
|
|||
pub use self::{count::CountRequest, flush::FlushRequest, pop::PopRequest, push::PushRequest};
|
||||
|
||||
#[cfg(feature = "search")]
|
||||
pub(crate) use self::{query::QueryCommand, suggest::SuggestCommand};
|
||||
pub(crate) use self::{list::ListCommand, query::QueryCommand, suggest::SuggestCommand};
|
||||
#[cfg(feature = "search")]
|
||||
pub use self::{query::QueryRequest, suggest::SuggestRequest};
|
||||
pub use self::{list::ListRequest, query::QueryRequest, suggest::SuggestRequest};
|
||||
|
||||
#[cfg(feature = "control")]
|
||||
pub(crate) use trigger::TriggerCommand;
|
||||
|
|
69
src/commands/list.rs
Normal file
69
src/commands/list.rs
Normal file
|
@ -0,0 +1,69 @@
|
|||
use super::StreamCommand;
|
||||
use crate::misc::Dest;
|
||||
use crate::protocol;
|
||||
use crate::result::*;
|
||||
|
||||
/// Parameters for the `suggest` command.
|
||||
#[derive(Debug)]
|
||||
pub struct ListRequest {
|
||||
/// Collection and bucket where we should enumerate all words in index.
|
||||
pub dest: Dest,
|
||||
/// Limit of result words.
|
||||
pub limit: Option<usize>,
|
||||
/// Offset of result words.
|
||||
pub offset: Option<usize>,
|
||||
}
|
||||
|
||||
impl ListRequest {
|
||||
/// Creates a base suggest request.
|
||||
pub fn new(dest: Dest) -> Self {
|
||||
Self {
|
||||
dest,
|
||||
limit: None,
|
||||
offset: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Set a limit for the request.
|
||||
pub fn limit(mut self, limit: usize) -> Self {
|
||||
self.limit = Some(limit);
|
||||
self
|
||||
}
|
||||
|
||||
/// Set an offset for the request.
|
||||
pub fn offset(mut self, offset: usize) -> Self {
|
||||
self.offset = Some(offset);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ListCommand {
|
||||
pub(crate) req: ListRequest,
|
||||
}
|
||||
|
||||
impl StreamCommand for ListCommand {
|
||||
type Response = Vec<String>;
|
||||
|
||||
fn request(&self) -> protocol::Request {
|
||||
let dest = &self.req.dest;
|
||||
|
||||
protocol::Request::List {
|
||||
collection: dest.collection().clone(),
|
||||
bucket: dest
|
||||
.bucket_opt()
|
||||
.cloned()
|
||||
.unwrap_or_else(|| String::from("default")),
|
||||
limit: self.req.limit,
|
||||
offset: self.req.offset,
|
||||
}
|
||||
}
|
||||
|
||||
fn receive(&self, res: protocol::Response) -> Result<Self::Response> {
|
||||
if let protocol::Response::Event(protocol::EventKind::List, _id, words) = res {
|
||||
Ok(words)
|
||||
} else {
|
||||
Err(Error::WrongResponse)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -76,6 +76,17 @@ impl Protocol {
|
|||
}
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
Request::List { collection, bucket, limit, offset } => {
|
||||
write!(res, "LIST {} {}", collection, bucket)?;
|
||||
if let Some(limit) = limit {
|
||||
write!(res, " LIMIT({})", limit)?;
|
||||
}
|
||||
if let Some(offset) = offset {
|
||||
write!(res, " OFFSET({})", offset)?;
|
||||
}
|
||||
}
|
||||
|
||||
Request::Trigger(triger_req) => match triger_req {
|
||||
TriggerRequest::Consolidate => write!(res, "TRIGGER consolidate")?,
|
||||
TriggerRequest::Backup(path) => {
|
||||
|
@ -123,6 +134,7 @@ impl Protocol {
|
|||
let event_kind = match segments.next() {
|
||||
Some("SUGGEST") => Ok(EventKind::Suggest),
|
||||
Some("QUERY") => Ok(EventKind::Query),
|
||||
Some("LIST") => Ok(EventKind::List),
|
||||
_ => Err(Error::WrongResponse),
|
||||
}?;
|
||||
|
||||
|
@ -202,6 +214,7 @@ pub struct StartedPayload {
|
|||
pub enum EventKind {
|
||||
Suggest,
|
||||
Query,
|
||||
List,
|
||||
}
|
||||
|
||||
//===========================================================================//
|
||||
|
@ -223,6 +236,12 @@ pub enum Request {
|
|||
word: String,
|
||||
limit: Option<usize>,
|
||||
},
|
||||
List {
|
||||
collection: String,
|
||||
bucket: String,
|
||||
limit: Option<usize>,
|
||||
offset: Option<usize>,
|
||||
},
|
||||
Query {
|
||||
collection: String,
|
||||
bucket: String,
|
||||
|
|
27
tests/list_command.rs
Normal file
27
tests/list_command.rs
Normal file
|
@ -0,0 +1,27 @@
|
|||
mod common;
|
||||
use common::*;
|
||||
|
||||
const COLLECTION: &str = "Search";
|
||||
|
||||
#[test]
|
||||
fn should_list_all_words() {
|
||||
let bucket = "suggest_nearest";
|
||||
let title = "Sweet Teriyaki Beef Skewers";
|
||||
|
||||
let dest = Dest::col_buc(COLLECTION, bucket);
|
||||
|
||||
let ingest_channel = ingest_start();
|
||||
ingest_channel
|
||||
.push(PushRequest::new(dest.clone().obj("1"), title))
|
||||
.unwrap();
|
||||
|
||||
consolidate();
|
||||
|
||||
let search_channel = search_start();
|
||||
match search_channel.list(ListRequest::new(dest.clone())) {
|
||||
Ok(object_ids) => assert_eq!(object_ids, vec!["beef", "skewers", "sweet", "teriyaki"]),
|
||||
Err(e) => unreachable!(),
|
||||
}
|
||||
|
||||
flush_bucket(COLLECTION, bucket);
|
||||
}
|
Loading…
Reference in a new issue