use NdbQueryPackage to call ndb::query multiple times
necessary to ensure we can retrieve reposts from ndb Signed-off-by: kernelkind <kernelkind@gmail.com>
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
use crate::{
|
||||
filter::{self, HybridFilter},
|
||||
filter::{self, HybridFilter, ValidKind},
|
||||
Error,
|
||||
};
|
||||
use nostrdb::{Filter, Note};
|
||||
@@ -15,8 +15,14 @@ pub fn hybrid_contacts_filter(
|
||||
add_pk: Option<&[u8; 32]>,
|
||||
with_hashtags: bool,
|
||||
) -> Result<HybridFilter, Error> {
|
||||
let local = filter::filter_from_tags(note, add_pk, with_hashtags)?
|
||||
.into_filter(vec![1], filter::default_limit());
|
||||
let local = vec![
|
||||
filter::filter_from_tags(note, add_pk, with_hashtags)?
|
||||
.into_query_package(ValidKind::One, filter::default_limit()),
|
||||
filter::filter_from_tags(note, add_pk, with_hashtags)?
|
||||
.into_query_package(ValidKind::Six, filter::default_limit()),
|
||||
filter::filter_from_tags(note, add_pk, with_hashtags)?
|
||||
.into_query_package(ValidKind::Zero, filter::default_limit()),
|
||||
];
|
||||
let remote = filter::filter_from_tags(note, add_pk, with_hashtags)?
|
||||
.into_filter(vec![1, 0], filter::default_remote_limit());
|
||||
|
||||
|
||||
@@ -213,7 +213,7 @@ pub struct FilteredTags {
|
||||
/// The local and remote filter are related but slightly different
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct SplitFilter {
|
||||
pub local: Vec<Filter>,
|
||||
pub local: Vec<NdbQueryPackage>,
|
||||
pub remote: Vec<Filter>,
|
||||
}
|
||||
|
||||
@@ -230,16 +230,23 @@ impl HybridFilter {
|
||||
HybridFilter::Unsplit(filter)
|
||||
}
|
||||
|
||||
pub fn split(local: Vec<Filter>, remote: Vec<Filter>) -> Self {
|
||||
pub fn split(local: Vec<NdbQueryPackage>, remote: Vec<Filter>) -> Self {
|
||||
HybridFilter::Split(SplitFilter { local, remote })
|
||||
}
|
||||
|
||||
pub fn local(&self) -> &[Filter] {
|
||||
pub fn local(&self) -> NdbQueryPackages {
|
||||
match self {
|
||||
Self::Split(split) => &split.local,
|
||||
Self::Split(split) => NdbQueryPackages {
|
||||
packages: split.local.iter().map(NdbQueryPackage::borrow).collect(),
|
||||
},
|
||||
|
||||
// local as the same as remote in unsplit
|
||||
Self::Unsplit(local) => local,
|
||||
Self::Unsplit(local) => NdbQueryPackages {
|
||||
packages: vec![NdbQueryPackageUnowned {
|
||||
filters: local,
|
||||
kind: None,
|
||||
}],
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -311,7 +311,7 @@ impl TimelineSub {
|
||||
let before = self.state.clone();
|
||||
match &mut self.state {
|
||||
SubState::NoSub { dependers } => {
|
||||
let Some(sub) = ndb_sub(ndb, filter.local(), "") else {
|
||||
let Some(sub) = ndb_sub(ndb, &filter.local().combined(), "") else {
|
||||
return;
|
||||
};
|
||||
|
||||
@@ -326,7 +326,7 @@ impl TimelineSub {
|
||||
dependers: _,
|
||||
} => {}
|
||||
SubState::RemoteOnly { remote, dependers } => {
|
||||
let Some(local) = ndb_sub(ndb, filter.local(), "") else {
|
||||
let Some(local) = ndb_sub(ndb, &filter.local().combined(), "") else {
|
||||
return;
|
||||
};
|
||||
self.state = SubState::Unified {
|
||||
|
||||
@@ -134,15 +134,22 @@ impl TimelineCache {
|
||||
}
|
||||
|
||||
let notes = if let FilterState::Ready(filters) = id.filters(txn, ndb) {
|
||||
if let Ok(results) = ndb.query(txn, filters.local(), 1000) {
|
||||
results
|
||||
.into_iter()
|
||||
.map(NoteRef::from_query_result)
|
||||
.collect()
|
||||
} else {
|
||||
debug!("got no results from TimelineCache lookup for {:?}", id);
|
||||
vec![]
|
||||
let mut notes = Vec::new();
|
||||
|
||||
for package in filters.local().packages {
|
||||
if let Ok(results) = ndb.query(txn, package.filters, 1000) {
|
||||
let cur_notes: Vec<NoteRef> = results
|
||||
.into_iter()
|
||||
.map(NoteRef::from_query_result)
|
||||
.collect();
|
||||
|
||||
notes.extend(cur_notes);
|
||||
} else {
|
||||
debug!("got no results from TimelineCache lookup for {:?}", id);
|
||||
}
|
||||
}
|
||||
|
||||
notes
|
||||
} else {
|
||||
// filter is not ready yet
|
||||
vec![]
|
||||
@@ -178,12 +185,20 @@ impl TimelineCache {
|
||||
let (mut open_result, timeline) = match notes_resp.vitality {
|
||||
Vitality::Stale(timeline) => {
|
||||
// The timeline cache is stale, let's update it
|
||||
let notes = find_new_notes(
|
||||
timeline.all_or_any_entries().latest(),
|
||||
timeline.subscription.get_filter()?.local(),
|
||||
txn,
|
||||
ndb,
|
||||
);
|
||||
let notes = {
|
||||
let mut notes = Vec::new();
|
||||
for package in timeline.subscription.get_filter()?.local().packages {
|
||||
let cur_notes = find_new_notes(
|
||||
timeline.all_or_any_entries().latest(),
|
||||
package.filters,
|
||||
txn,
|
||||
ndb,
|
||||
);
|
||||
notes.extend(cur_notes);
|
||||
}
|
||||
notes
|
||||
};
|
||||
|
||||
let open_result = if notes.is_empty() {
|
||||
None
|
||||
} else {
|
||||
|
||||
@@ -3,6 +3,7 @@ use crate::search::SearchQuery;
|
||||
use crate::timeline::{Timeline, TimelineTab};
|
||||
use enostr::{Filter, NoteId, Pubkey};
|
||||
use nostrdb::{Ndb, Transaction};
|
||||
use notedeck::filter::{NdbQueryPackage, ValidKind};
|
||||
use notedeck::{
|
||||
contacts::{contacts_filter, hybrid_contacts_filter},
|
||||
filter::{self, default_limit, default_remote_limit, HybridFilter},
|
||||
@@ -728,15 +729,29 @@ fn last_per_pubkey_filter_state(ndb: &Ndb, pk: &Pubkey) -> FilterState {
|
||||
}
|
||||
|
||||
fn profile_filter(pk: &[u8; 32]) -> HybridFilter {
|
||||
let local = vec![
|
||||
NdbQueryPackage {
|
||||
filters: vec![Filter::new()
|
||||
.authors([pk])
|
||||
.kinds([1])
|
||||
.limit(default_limit())
|
||||
.build()],
|
||||
kind: ValidKind::One,
|
||||
},
|
||||
NdbQueryPackage {
|
||||
filters: vec![Filter::new()
|
||||
.authors([pk])
|
||||
.kinds([6])
|
||||
.limit(default_limit())
|
||||
.build()],
|
||||
kind: ValidKind::Six,
|
||||
},
|
||||
];
|
||||
HybridFilter::split(
|
||||
local,
|
||||
vec![Filter::new()
|
||||
.authors([pk])
|
||||
.kinds([1])
|
||||
.limit(default_limit())
|
||||
.build()],
|
||||
vec![Filter::new()
|
||||
.authors([pk])
|
||||
.kinds([1, 0])
|
||||
.kinds([1, 6, 0])
|
||||
.limit(default_remote_limit())
|
||||
.build()],
|
||||
)
|
||||
|
||||
@@ -676,18 +676,32 @@ fn setup_initial_timeline(
|
||||
timeline.subscription, timeline.filter
|
||||
);
|
||||
|
||||
let mut lim = 0i32;
|
||||
for filter in filters.local() {
|
||||
lim += filter.limit().unwrap_or(1) as i32;
|
||||
}
|
||||
let notes = {
|
||||
let mut notes = Vec::new();
|
||||
|
||||
debug!("setup_initial_timeline: limit for local filter is {}", lim);
|
||||
for package in filters.local().packages {
|
||||
let mut lim = 0i32;
|
||||
for filter in package.filters {
|
||||
lim += filter.limit().unwrap_or(1) as i32;
|
||||
}
|
||||
|
||||
let notes: Vec<NoteRef> = ndb
|
||||
.query(txn, filters.local(), lim)?
|
||||
.into_iter()
|
||||
.map(NoteRef::from_query_result)
|
||||
.collect();
|
||||
debug!("setup_initial_timeline: limit for local filter is {}", lim);
|
||||
|
||||
let cur_notes: Vec<NoteRef> = ndb
|
||||
.query(txn, package.filters, lim)?
|
||||
.into_iter()
|
||||
.map(NoteRef::from_query_result)
|
||||
.collect();
|
||||
tracing::debug!(
|
||||
"Found {} notes for kind: {:?}",
|
||||
cur_notes.len(),
|
||||
package.kind
|
||||
);
|
||||
notes.extend(&cur_notes);
|
||||
}
|
||||
|
||||
notes
|
||||
};
|
||||
|
||||
if let Some(pks) = timeline.insert_new(txn, ndb, note_cache, ¬es) {
|
||||
pks.process(ndb, txn, unknown_ids);
|
||||
|
||||
Reference in New Issue
Block a user