Implement checking for deleted coordinate
This commit is contained in:
parent
1cd2a49e35
commit
255905021c
2 changed files with 148 additions and 29 deletions
|
@ -5,7 +5,9 @@ use crate::{
|
|||
};
|
||||
use async_trait::async_trait;
|
||||
use deadpool_sqlite::{Config, Object, Pool, Runtime};
|
||||
use nostr::{nips::nip01::Coordinate, Event, EventId, Filter, RelayMessage, Timestamp, Url};
|
||||
use nostr::{
|
||||
nips::nip01::Coordinate, Event, EventId, Filter, RelayMessage, TagKind, Timestamp, Url,
|
||||
};
|
||||
use nostr_database::{Backend, DatabaseOptions, NostrDatabase, Order};
|
||||
use rusqlite::Row;
|
||||
use sea_query::{extension::sqlite::SqliteExpr, Order as SqOrder, Query, SqliteQueryBuilder};
|
||||
|
@ -544,26 +546,36 @@ impl NostrSqlite {
|
|||
// Insert into Tags table
|
||||
log::debug!("inserting new event into tags");
|
||||
for tag in event.tags.clone() {
|
||||
let tag = tag.to_vec();
|
||||
if tag.len() >= 2 {
|
||||
let tag_name = &tag[0];
|
||||
let tag_value = &tag[1];
|
||||
if tag_name.len() == 1 {
|
||||
let (sql, values) = Query::insert()
|
||||
.into_table(TagsTable::Table)
|
||||
.columns([TagsTable::Tag, TagsTable::Value, TagsTable::EventId])
|
||||
.values_panic([
|
||||
tag_name.into(),
|
||||
tag_value.into(),
|
||||
id.clone().into(),
|
||||
])
|
||||
.build_rusqlite(SqliteQueryBuilder);
|
||||
if Self::tag_is_indexable(&tag) {
|
||||
let tag = tag.to_vec();
|
||||
if tag.len() >= 2 {
|
||||
let tag_name = &tag[0];
|
||||
let tag_value = &tag[1];
|
||||
if tag_name.len() == 1 {
|
||||
let (sql, values) = Query::insert()
|
||||
.into_table(TagsTable::Table)
|
||||
.columns([
|
||||
TagsTable::Tag,
|
||||
TagsTable::Value,
|
||||
TagsTable::EventId,
|
||||
])
|
||||
.values_panic([
|
||||
tag_name.into(),
|
||||
tag_value.into(),
|
||||
id.clone().into(),
|
||||
])
|
||||
.build_rusqlite(SqliteQueryBuilder);
|
||||
|
||||
if let Err(err) = tx.execute(sql.as_str(), &*values.as_params()) {
|
||||
log::error!("Error inserting event into 'tags' table: {}", err);
|
||||
tx.rollback().unwrap();
|
||||
if let Err(err) = tx.execute(sql.as_str(), &*values.as_params())
|
||||
{
|
||||
log::error!(
|
||||
"Error inserting event into 'tags' table: {}",
|
||||
err
|
||||
);
|
||||
tx.rollback().unwrap();
|
||||
|
||||
return Ok(false);
|
||||
return Ok(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -586,6 +598,22 @@ impl NostrSqlite {
|
|||
event_saved
|
||||
}
|
||||
|
||||
fn tag_is_indexable(tag: &nostr::Tag) -> bool {
|
||||
matches!(
|
||||
tag.kind(),
|
||||
TagKind::E
|
||||
| TagKind::P
|
||||
| TagKind::UpperP
|
||||
| TagKind::A
|
||||
| TagKind::D
|
||||
| TagKind::G
|
||||
| TagKind::I
|
||||
| TagKind::M
|
||||
| TagKind::R
|
||||
| TagKind::T
|
||||
)
|
||||
}
|
||||
|
||||
async fn has_event_already_been_saved(&self, event_id: &EventId) -> Result<bool, Error> {
|
||||
match self.get_event_by_id(*event_id).await {
|
||||
Ok(_) => Ok(true),
|
||||
|
@ -1136,7 +1164,55 @@ impl NostrSqlite {
|
|||
coordinate: &Coordinate,
|
||||
timestamp: Timestamp,
|
||||
) -> Result<bool, Error> {
|
||||
Ok(true)
|
||||
let Ok(connection) = self.get_connection().await else {
|
||||
return Err(Error::internal_with_message("Unable to get DB connection"));
|
||||
};
|
||||
|
||||
let ident = if coordinate.identifier.is_empty() {
|
||||
format!("{}:{}", coordinate.kind, coordinate.pubkey)
|
||||
} else {
|
||||
format!(
|
||||
"{}:{}:{}",
|
||||
coordinate.kind, coordinate.pubkey, coordinate.identifier
|
||||
)
|
||||
};
|
||||
|
||||
let Ok(query_result) = connection
|
||||
.interact(move |conn: &mut rusqlite::Connection| -> Result<bool, Error> {
|
||||
let (sql, value) = Query::select()
|
||||
.from(EventsTable::Table)
|
||||
.columns([EventsTable::EventId, EventsTable::CreatedAt])
|
||||
.left_join(
|
||||
TagsTable::Table,
|
||||
sea_query::Expr::col((TagsTable::Table, TagsTable::EventId))
|
||||
.equals((EventsTable::Table, EventsTable::EventId)),
|
||||
)
|
||||
.and_where(sea_query::Expr::col((TagsTable::Table, TagsTable::Tag)).eq("a"))
|
||||
.and_where(sea_query::Expr::col((TagsTable::Table, TagsTable::Value)).eq(ident))
|
||||
.and_where(
|
||||
sea_query::Expr::col((EventsTable::Table, EventsTable::CreatedAt))
|
||||
.gte(timestamp.as_i64()),
|
||||
)
|
||||
.limit(1)
|
||||
.build_rusqlite(SqliteQueryBuilder);
|
||||
|
||||
let mut stmt = conn.prepare(sql.as_str()).unwrap();
|
||||
let mut rows = stmt.query(&*value.as_params()).unwrap();
|
||||
|
||||
if let Ok(Some(record)) = rows.next() {
|
||||
return Ok(false)
|
||||
}
|
||||
|
||||
Ok(true)
|
||||
})
|
||||
.await
|
||||
else {
|
||||
return Err(Error::internal_with_message(
|
||||
"Failed to execute query 'get_event_by_id'",
|
||||
));
|
||||
};
|
||||
|
||||
query_result
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1196,7 +1272,7 @@ impl NostrDatabase for NostrSqlite {
|
|||
coordinate: &Coordinate,
|
||||
timestamp: Timestamp,
|
||||
) -> Result<bool, Self::Err> {
|
||||
todo!()
|
||||
self.has_coordinate_been_deleted(coordinate, timestamp).await
|
||||
}
|
||||
|
||||
/// Set [`EventId`] as seen by relay
|
||||
|
@ -1245,7 +1321,9 @@ impl NostrDatabase for NostrSqlite {
|
|||
&self,
|
||||
filter: Filter,
|
||||
) -> Result<Vec<(EventId, Timestamp)>, Self::Err> {
|
||||
todo!()
|
||||
Err(Error::internal_with_message(
|
||||
"negentropy is not currently supported",
|
||||
))
|
||||
}
|
||||
|
||||
/// Wipe all data
|
||||
|
@ -1577,4 +1655,45 @@ mod tests {
|
|||
|
||||
assert_eq!(result.len(), 1)
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn save_event_with_a_tag() {
|
||||
let config = Arc::new(ServiceConfig::new());
|
||||
let db = NostrSqlite::new(config).await;
|
||||
|
||||
let keys = nostr::Keys::generate();
|
||||
let d_tag = nostr::Tag::Identifier("test".to_string());
|
||||
let coordinate_event =
|
||||
nostr::EventBuilder::new(nostr::Kind::TextNote, "hello", vec![d_tag.clone()])
|
||||
.to_event(&keys)
|
||||
.unwrap();
|
||||
db.save_event(&coordinate_event).await.unwrap();
|
||||
|
||||
let coordinate = nostr::nips::nip01::Coordinate::new(
|
||||
nostr::Kind::CategorizedBookmarkList,
|
||||
coordinate_event.pubkey,
|
||||
)
|
||||
.identifier("test");
|
||||
|
||||
let a_tag = nostr::Tag::A {
|
||||
kind: nostr::Kind::CategorizedBookmarkList,
|
||||
public_key: keys.public_key(),
|
||||
identifier: "test".to_string(),
|
||||
relay_url: None,
|
||||
};
|
||||
let event =
|
||||
nostr::EventBuilder::new(nostr::Kind::CategorizedBookmarkList, "", vec![d_tag, a_tag])
|
||||
.to_event(&keys)
|
||||
.unwrap();
|
||||
|
||||
let result = db.save_event(&event).await.unwrap();
|
||||
|
||||
let ts = nostr::Timestamp::now();
|
||||
let res = db
|
||||
.has_coordinate_been_deleted(&coordinate, ts)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
dbg!(res);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue