From a488c00a2e4daf0f9d4947b4e06fb66b92b7d733 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Renault?= Date: Fri, 26 Jul 2019 13:27:38 +0200 Subject: [PATCH] feat: Use RustyLine in the query-database example --- meilidb/Cargo.toml | 1 + meilidb/examples/query-database.rs | 114 +++++++++++++++-------------- 2 files changed, 60 insertions(+), 55 deletions(-) diff --git a/meilidb/Cargo.toml b/meilidb/Cargo.toml index 8ba89f212..7208067f0 100644 --- a/meilidb/Cargo.toml +++ b/meilidb/Cargo.toml @@ -18,6 +18,7 @@ meilidb-core = { path = "../meilidb-core", version = "0.1.0" } quickcheck = "0.8.2" rand = "0.6.5" rand_xorshift = "0.1.1" +rustyline = { version = "5.0.0", default-features = false } serde = { version = "1.0.91" , features = ["derive"] } serde_json = "1.0.39" structopt = "0.2.15" diff --git a/meilidb/examples/query-database.rs b/meilidb/examples/query-database.rs index 72244d1b8..f9e2f8389 100644 --- a/meilidb/examples/query-database.rs +++ b/meilidb/examples/query-database.rs @@ -3,16 +3,17 @@ static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc; use std::collections::btree_map::{BTreeMap, Entry}; use std::collections::{HashMap, HashSet}; -use std::iter::FromIterator; -use std::io::{self, Write}; -use std::time::{Instant, Duration}; -use std::path::PathBuf; use std::error::Error; +use std::io::{self, Write}; +use std::iter::FromIterator; +use std::path::PathBuf; +use std::time::{Instant, Duration}; use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor}; use structopt::StructOpt; -use meilidb_core::Highlight; +use rustyline::{Editor, Config}; +use meilidb_core::Highlight; use meilidb_data::Database; use meilidb_schema::SchemaAttr; @@ -140,9 +141,6 @@ fn main() -> Result<(), Box> { let start = Instant::now(); let database = Database::start_default(&opt.database_path)?; - let mut buffer = String::new(); - let input = io::stdin(); - let index = database.open_index("test")?.unwrap(); let schema = index.schema(); @@ -151,65 +149,71 @@ fn main() -> Result<(), Box> { let fields = opt.displayed_fields.iter().map(String::as_str); let fields = HashSet::from_iter(fields); - loop { - print!("Searching for: "); - io::stdout().flush()?; + let config = Config::builder().auto_add_history(true).build(); + let mut readline = Editor::<()>::with_config(config); + let _ = readline.load_history("query-history.txt"); - if input.read_line(&mut buffer)? == 0 { break } - let query = buffer.trim_end_matches('\n'); + for result in readline.iter("Searching for: ") { + match result { + Ok(query) => { + let start_total = Instant::now(); - let start_total = Instant::now(); + let builder = index.query_builder(); + let documents = builder.query(&query, 0..opt.number_results)?; - let builder = index.query_builder(); - let documents = builder.query(query, 0..opt.number_results)?; + let mut retrieve_duration = Duration::default(); - let mut retrieve_duration = Duration::default(); + let number_of_documents = documents.len(); + for mut doc in documents { - let number_of_documents = documents.len(); - for mut doc in documents { + doc.highlights.sort_unstable_by_key(|m| (m.char_index, m.char_length)); - doc.highlights.sort_unstable_by_key(|m| (m.char_index, m.char_length)); + let start_retrieve = Instant::now(); + let result = index.document::(Some(&fields), doc.id); + retrieve_duration += start_retrieve.elapsed(); - let start_retrieve = Instant::now(); - let result = index.document::(Some(&fields), doc.id); - retrieve_duration += start_retrieve.elapsed(); + match result { + Ok(Some(document)) => { + for (name, text) in document { + print!("{}: ", name); - match result { - Ok(Some(document)) => { - for (name, text) in document { - print!("{}: ", name); - - let attr = schema.attribute(&name).unwrap(); - let highlights = doc.highlights.iter() - .filter(|m| SchemaAttr::new(m.attribute) == attr) - .cloned(); - let (text, highlights) = crop_text(&text, highlights, opt.char_context); - let areas = create_highlight_areas(&text, &highlights); - display_highlights(&text, &areas)?; - println!(); + let attr = schema.attribute(&name).unwrap(); + let highlights = doc.highlights.iter() + .filter(|m| SchemaAttr::new(m.attribute) == attr) + .cloned(); + let (text, highlights) = crop_text(&text, highlights, opt.char_context); + let areas = create_highlight_areas(&text, &highlights); + display_highlights(&text, &areas)?; + println!(); + } + }, + Ok(None) => eprintln!("missing document"), + Err(e) => eprintln!("{}", e), } - }, - Ok(None) => eprintln!("missing document"), - Err(e) => eprintln!("{}", e), + + let mut matching_attributes = HashSet::new(); + for highlight in doc.highlights { + let attr = SchemaAttr::new(highlight.attribute); + let name = schema.attribute_name(attr); + matching_attributes.insert(name); + } + + let matching_attributes = Vec::from_iter(matching_attributes); + println!("matching in: {:?}", matching_attributes); + + println!(); + } + + eprintln!("document field retrieve took {:.2?}", retrieve_duration); + eprintln!("===== Found {} results in {:.2?} =====", number_of_documents, start_total.elapsed()); + }, + Err(err) => { + println!("Error: {:?}", err); + break } - - let mut matching_attributes = HashSet::new(); - for highlight in doc.highlights { - let attr = SchemaAttr::new(highlight.attribute); - let name = schema.attribute_name(attr); - matching_attributes.insert(name); - } - - let matching_attributes = Vec::from_iter(matching_attributes); - println!("matching in: {:?}", matching_attributes); - - println!(); } - - eprintln!("document field retrieve took {:.2?}", retrieve_duration); - eprintln!("===== Found {} results in {:.2?} =====", number_of_documents, start_total.elapsed()); - buffer.clear(); } + readline.save_history("query-history.txt").unwrap(); Ok(()) }