mirror of
https://git.meli.delivery/meli/meli
synced 2024-11-17 03:26:20 +00:00
ui: add query translation to SQL SELECTs
This commit is contained in:
parent
7936aef476
commit
e396b2f72b
@ -142,6 +142,8 @@ impl std::ops::BitOr for Query {
|
||||
}
|
||||
}
|
||||
|
||||
pub use query_parser::query;
|
||||
|
||||
pub mod query_parser {
|
||||
use super::Query::{self, *};
|
||||
use melib::parsec::*;
|
||||
@ -173,7 +175,7 @@ pub mod query_parser {
|
||||
pub fn not<'a>() -> impl Parser<'a, Query> {
|
||||
move |input| {
|
||||
whitespace_wrap(either(
|
||||
match_literal_anycase("or"),
|
||||
match_literal_anycase("not"),
|
||||
match_literal_anycase("!"),
|
||||
))
|
||||
.parse(input)
|
||||
@ -213,8 +215,8 @@ pub mod query_parser {
|
||||
Ok(q)
|
||||
} else if let Ok(q) = from().parse(input) {
|
||||
Ok(q)
|
||||
} else if let Ok(q) = not().parse(input) {
|
||||
Ok(q)
|
||||
} else if let Ok((rest, query_a)) = not().parse(input) {
|
||||
Ok((rest, Not(Box::new(query_a))))
|
||||
} else if let Ok((rest, query_a)) = {
|
||||
let result = literal().parse(input);
|
||||
if result.is_ok()
|
||||
|
@ -19,6 +19,9 @@
|
||||
* along with meli. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use crate::cache::query;
|
||||
use crate::cache::Query::{self, *};
|
||||
use crate::melib::parsec::Parser;
|
||||
use melib::{
|
||||
backends::MailBackend,
|
||||
email::{Envelope, EnvelopeHash},
|
||||
@ -299,13 +302,25 @@ pub fn search(
|
||||
SortOrder::Desc => "DESC",
|
||||
};
|
||||
|
||||
/*
|
||||
debug!("SELECT hash FROM envelopes INNER JOIN fts ON fts.rowid = envelopes.id WHERE fts MATCH ? ORDER BY {} {};", sort_field, sort_order);
|
||||
let mut stmt = conn.prepare(
|
||||
format!("SELECT hash FROM envelopes INNER JOIN fts ON fts.rowid = envelopes.id WHERE fts MATCH ? ORDER BY {} {};", sort_field, sort_order).as_str())
|
||||
.map_err(|e| MeliError::new(e.to_string()))?;
|
||||
*/
|
||||
let mut stmt = conn
|
||||
.prepare(
|
||||
debug!(format!(
|
||||
"SELECT hash FROM envelopes WHERE {} ORDER BY {} {};",
|
||||
query_to_sql(&query().parse(term)?.1),
|
||||
sort_field,
|
||||
sort_order
|
||||
))
|
||||
.as_str(),
|
||||
)
|
||||
.map_err(|e| MeliError::new(e.to_string()))?;
|
||||
|
||||
let results = stmt
|
||||
.query_map(&[fts5_bareword(term)], |row| Ok(row.get(0)?))
|
||||
.query_map(rusqlite::NO_PARAMS, |row| Ok(row.get(0)?))
|
||||
.map_err(|e| MeliError::new(e.to_string()))?
|
||||
.map(|r: std::result::Result<Vec<u8>, rusqlite::Error>| {
|
||||
Ok(u64::from_be_bytes(
|
||||
@ -339,3 +354,75 @@ pub fn from(term: &str) -> Result<StackVec<EnvelopeHash>> {
|
||||
.collect::<Result<StackVec<EnvelopeHash>>>();
|
||||
results
|
||||
}
|
||||
|
||||
pub fn query_to_sql(q: &Query) -> String {
|
||||
fn rec(q: &Query, s: &mut String) {
|
||||
match q {
|
||||
Subject(t) => {
|
||||
s.push_str(" subject LIKE \"%");
|
||||
s.extend(escape_double_quote(t).chars());
|
||||
s.push_str("%\"");
|
||||
}
|
||||
From(t) => {
|
||||
s.push_str(" _from LIKE \"%");
|
||||
s.extend(escape_double_quote(t).chars());
|
||||
s.push_str("%\"");
|
||||
}
|
||||
AllText(t) => {
|
||||
s.push_str(" body_text LIKE \"%");
|
||||
s.extend(escape_double_quote(t).chars());
|
||||
s.push_str("%\"");
|
||||
}
|
||||
And(q1, q2) => {
|
||||
s.push_str(" (");
|
||||
rec(q1, s);
|
||||
s.push_str(") ");
|
||||
|
||||
s.push_str(" AND ");
|
||||
s.push_str(" (");
|
||||
rec(q2, s);
|
||||
s.push_str(") ");
|
||||
}
|
||||
Or(q1, q2) => {
|
||||
s.push_str(" (");
|
||||
rec(q1, s);
|
||||
s.push_str(") ");
|
||||
s.push_str(" OR ");
|
||||
s.push_str(" (");
|
||||
rec(q2, s);
|
||||
s.push_str(") ");
|
||||
}
|
||||
Not(q) => {
|
||||
s.push_str(" NOT ");
|
||||
s.push_str("(");
|
||||
rec(q, s);
|
||||
s.push_str(")");
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
let mut ret = String::new();
|
||||
rec(q, &mut ret);
|
||||
ret
|
||||
|
||||
//"SELECT hash FROM envelopes INNER JOIN fts ON fts.rowid = envelopes.id WHERE fts MATCH ? ORDER BY {} {};"
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_query_to_sql() {
|
||||
assert_eq!(
|
||||
" subject LIKE \"%test%\" AND body_text LIKE \"%i%\"",
|
||||
&query_to_sql(&query().parse_complete("subject: test and i").unwrap().1)
|
||||
);
|
||||
assert_eq!(
|
||||
" subject LIKE \"%github%\" OR ( _from LIKE \"%epilys%\" AND ( subject LIKE \"%lib%\" OR subject LIKE \"%meli%\") ) ",
|
||||
&query_to_sql(
|
||||
&query()
|
||||
.parse_complete(
|
||||
"subject: github or (from: epilys and (subject:lib or subject: meli))"
|
||||
)
|
||||
.unwrap()
|
||||
.1
|
||||
)
|
||||
);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user