mirror of
https://github.com/ankitects/anki.git
synced 2025-09-18 14:02:21 -04:00
add note searching
This commit is contained in:
parent
aee64016ac
commit
a5787781d7
7 changed files with 63 additions and 7 deletions
|
@ -25,7 +25,7 @@ message BackendInput {
|
|||
SchedTimingTodayIn sched_timing_today = 17;
|
||||
Empty deck_tree = 18;
|
||||
SearchCardsIn search_cards = 19;
|
||||
// BrowserRowsIn browser_rows = 20;
|
||||
SearchNotesIn search_notes = 20;
|
||||
RenderCardIn render_card = 21;
|
||||
int64 local_minutes_west = 22;
|
||||
string strip_av_tags = 23;
|
||||
|
@ -63,7 +63,7 @@ message BackendOutput {
|
|||
TemplateRequirementsOut template_requirements = 16;
|
||||
DeckTreeOut deck_tree = 18;
|
||||
SearchCardsOut search_cards = 19;
|
||||
// BrowserRowsOut browser_rows = 20;
|
||||
SearchNotesOut search_notes = 20;
|
||||
RenderCardOut render_card = 21;
|
||||
string add_media_file = 26;
|
||||
Empty sync_media = 27;
|
||||
|
@ -333,3 +333,11 @@ message SortOrder {
|
|||
string custom = 3;
|
||||
}
|
||||
}
|
||||
|
||||
message SearchNotesIn {
|
||||
string search = 1;
|
||||
}
|
||||
|
||||
message SearchNotesOut {
|
||||
repeated int64 note_ids = 2;
|
||||
}
|
||||
|
|
|
@ -616,11 +616,11 @@ where c.nid = n.id and c.id in %s group by nid"""
|
|||
# Finding cards
|
||||
##########################################################################
|
||||
|
||||
def findCards(self, query: str, order: Union[bool, str] = False) -> Sequence[int]:
|
||||
def find_cards(self, query: str, order: Union[bool, str] = False) -> Sequence[int]:
|
||||
return self.backend.search_cards(query, order)
|
||||
|
||||
def findNotes(self, query: str) -> Any:
|
||||
return anki.find.Finder(self).findNotes(query)
|
||||
def find_notes(self, query: str) -> Sequence[int]:
|
||||
return self.backend.search_notes(query)
|
||||
|
||||
def findReplace(
|
||||
self,
|
||||
|
@ -636,6 +636,9 @@ where c.nid = n.id and c.id in %s group by nid"""
|
|||
def findDupes(self, fieldName: str, search: str = "") -> List[Tuple[Any, list]]:
|
||||
return anki.find.findDupes(self, fieldName, search)
|
||||
|
||||
findCards = find_cards
|
||||
findNotes = find_notes
|
||||
|
||||
# Stats
|
||||
##########################################################################
|
||||
|
||||
|
|
|
@ -595,7 +595,7 @@ def findDupes(
|
|||
# limit search to notes with applicable field name
|
||||
if search:
|
||||
search = "(" + search + ") "
|
||||
search += "'%s:*'" % fieldName
|
||||
search += '"%s:*"' % fieldName.replace('"', '"')
|
||||
# go through notes
|
||||
vals: Dict[str, List[int]] = {}
|
||||
dupes = []
|
||||
|
|
|
@ -434,6 +434,11 @@ class RustBackend:
|
|||
pb.BackendInput(search_cards=pb.SearchCardsIn(search=search, order=mode))
|
||||
).search_cards.card_ids
|
||||
|
||||
def search_notes(self, search: str) -> Sequence[int]:
|
||||
return self._run_command(
|
||||
pb.BackendInput(search_notes=pb.SearchNotesIn(search=search))
|
||||
).search_notes.note_ids
|
||||
|
||||
|
||||
def translate_string_in(
|
||||
key: TR, **kwargs: Union[str, int, float]
|
||||
|
|
|
@ -14,7 +14,7 @@ use crate::media::sync::MediaSyncProgress;
|
|||
use crate::media::MediaManager;
|
||||
use crate::sched::cutoff::{local_minutes_west_for_stamp, sched_timing_today_v2_new};
|
||||
use crate::sched::timespan::{answer_button_time, learning_congrats, studied_today, time_span};
|
||||
use crate::search::{search_cards, SortMode};
|
||||
use crate::search::{search_cards, search_notes, SortMode};
|
||||
use crate::template::{
|
||||
render_card, without_legacy_template_directives, FieldMap, FieldRequirements, ParsedTemplate,
|
||||
RenderedNode,
|
||||
|
@ -246,6 +246,7 @@ impl Backend {
|
|||
OValue::CloseCollection(Empty {})
|
||||
}
|
||||
Value::SearchCards(input) => OValue::SearchCards(self.search_cards(input)?),
|
||||
Value::SearchNotes(input) => OValue::SearchNotes(self.search_notes(input)?),
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -597,6 +598,15 @@ impl Backend {
|
|||
})
|
||||
})
|
||||
}
|
||||
|
||||
fn search_notes(&self, input: pb::SearchNotesIn) -> Result<pb::SearchNotesOut> {
|
||||
self.with_col(|col| {
|
||||
col.with_ctx(|ctx| {
|
||||
let nids = search_notes(ctx, &input.search)?;
|
||||
Ok(pb::SearchNotesOut { note_ids: nids })
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn translate_arg_to_fluent_val(arg: &pb::TranslateArgValue) -> FluentValue {
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
mod cards;
|
||||
mod notes;
|
||||
mod parser;
|
||||
mod sqlwriter;
|
||||
|
||||
pub(crate) use cards::{search_cards, SortMode};
|
||||
pub(crate) use notes::search_notes;
|
||||
|
|
28
rslib/src/search/notes.rs
Normal file
28
rslib/src/search/notes.rs
Normal file
|
@ -0,0 +1,28 @@
|
|||
// Copyright: Ankitects Pty Ltd and contributors
|
||||
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
|
||||
use super::{parser::Node, sqlwriter::node_to_sql};
|
||||
use crate::collection::RequestContext;
|
||||
use crate::err::Result;
|
||||
use crate::search::parser::parse;
|
||||
use crate::types::ObjID;
|
||||
|
||||
pub(crate) fn search_notes<'a, 'b>(
|
||||
req: &'a mut RequestContext<'b>,
|
||||
search: &'a str,
|
||||
) -> Result<Vec<ObjID>> {
|
||||
let top_node = Node::Group(parse(search)?);
|
||||
let (sql, args) = node_to_sql(req, &top_node)?;
|
||||
|
||||
let sql = format!(
|
||||
"select n.id from cards c, notes n where c.nid=n.id and {}",
|
||||
sql
|
||||
);
|
||||
|
||||
let mut stmt = req.storage.db.prepare(&sql)?;
|
||||
let ids: Vec<i64> = stmt
|
||||
.query_map(&args, |row| row.get(0))?
|
||||
.collect::<std::result::Result<_, _>>()?;
|
||||
|
||||
Ok(ids)
|
||||
}
|
Loading…
Reference in a new issue