feat: Improve Tag search NIP-12
Build and Push Docker Image / build_docker_image (push) Failing after 15m2s
Build and Push Docker Image / build_docker_image (push) Failing after 15m2s
modified: Cargo.lock modified: Cargo.toml modified: src/database.rs modified: src/nostr/event.rs modified: src/nostr/filter.rs
This commit is contained in:
Generated
+1
-1
@@ -891,7 +891,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nostr-relay"
|
||||
version = "1.0.0"
|
||||
version = "1.0.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"env_logger",
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "nostr-relay"
|
||||
version = "1.0.0"
|
||||
version = "1.0.1"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
|
||||
@@ -28,6 +28,14 @@ pub async fn init_database(pool: &SqlitePool) -> Result<()> {
|
||||
d_tag TEXT,
|
||||
deleted_at INTEGER DEFAULT (unixepoch())
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS event_tags (
|
||||
event_id TEXT NOT NULL,
|
||||
tag_name TEXT NOT NULL,
|
||||
tag_value TEXT NOT NULL,
|
||||
created_at INTEGER NOT NULL,
|
||||
FOREIGN KEY(event_id) REFERENCES events(id) ON DELETE CASCADE
|
||||
);
|
||||
"#;
|
||||
|
||||
let create_indexes = vec![
|
||||
@@ -39,6 +47,7 @@ pub async fn init_database(pool: &SqlitePool) -> Result<()> {
|
||||
"CREATE INDEX IF NOT EXISTS idx_events_pubkey_kind_d_tag ON events(pubkey, kind, d_tag);",
|
||||
"CREATE INDEX IF NOT EXISTS idx_deleted_events_pubkey ON deleted_events(pubkey, event_id);",
|
||||
"CREATE INDEX IF NOT EXISTS idx_deleted_events_kind_d_tag ON deleted_events(kind, pubkey, d_tag);",
|
||||
"CREATE INDEX IF NOT EXISTS idx_event_tags_name_value_created ON event_tags(tag_name, tag_value, created_at DESC);",
|
||||
];
|
||||
|
||||
query(create_events_table).execute(pool).await?;
|
||||
|
||||
+30
-13
@@ -182,6 +182,7 @@ impl NostrEventExt for NostrEvent {
|
||||
// 保存事件到数据库,并处理可替换事件和删除事件
|
||||
async fn save(&self, pool: &SqlitePool) -> Result<(), anyhow::Error> {
|
||||
let tags_json = serde_json::to_string(&self.tags).unwrap();
|
||||
let mut tx = pool.begin().await?;
|
||||
|
||||
// 提取 d_tag
|
||||
let d_tag = self
|
||||
@@ -206,7 +207,7 @@ impl NostrEventExt for NostrEvent {
|
||||
sqlx::query("DELETE FROM events WHERE id = ? AND pubkey = ?")
|
||||
.bind(event_id_to_delete)
|
||||
.bind(&self.pubkey)
|
||||
.execute(pool)
|
||||
.execute(&mut *tx)
|
||||
.await?;
|
||||
if result.rows_affected() > 0 {
|
||||
info!(
|
||||
@@ -219,7 +220,7 @@ impl NostrEventExt for NostrEvent {
|
||||
.bind(event_id_to_delete)
|
||||
.bind(&self.pubkey)
|
||||
.bind(self.created_at as i64)
|
||||
.execute(pool)
|
||||
.execute(&mut *tx)
|
||||
.await?;
|
||||
if result.rows_affected() > 0 {
|
||||
info!(
|
||||
@@ -252,7 +253,7 @@ impl NostrEventExt for NostrEvent {
|
||||
.bind(&self.pubkey)
|
||||
.bind(tag_d_vector[2])
|
||||
.bind(self.created_at as i64)
|
||||
.execute(pool)
|
||||
.execute(&mut *tx)
|
||||
.await?;
|
||||
if result.rows_affected() > 0 {
|
||||
info!(
|
||||
@@ -266,7 +267,7 @@ impl NostrEventExt for NostrEvent {
|
||||
.bind(&self.pubkey)
|
||||
.bind(tag_d_vector[2])
|
||||
.bind(self.created_at as i64)
|
||||
.execute(pool)
|
||||
.execute(&mut *tx)
|
||||
.await?;
|
||||
if result.rows_affected() > 0 {
|
||||
info!(
|
||||
@@ -303,7 +304,7 @@ impl NostrEventExt for NostrEvent {
|
||||
.bind(&self.pubkey)
|
||||
.bind(self.kind)
|
||||
.bind(self.created_at as i64)
|
||||
.fetch_optional(pool)
|
||||
.fetch_optional(&mut *tx)
|
||||
.await?;
|
||||
|
||||
if is_deleted.is_some() {
|
||||
@@ -313,7 +314,7 @@ impl NostrEventExt for NostrEvent {
|
||||
let created_at: Option<u64> = sqlx::query_scalar(sql)
|
||||
.bind(&self.pubkey)
|
||||
.bind(self.kind)
|
||||
.fetch_optional(pool)
|
||||
.fetch_optional(&mut *tx)
|
||||
.await?;
|
||||
|
||||
if let Some(prev_created_at) = created_at {
|
||||
@@ -322,7 +323,7 @@ impl NostrEventExt for NostrEvent {
|
||||
sqlx::query(sql)
|
||||
.bind(&self.pubkey)
|
||||
.bind(self.kind)
|
||||
.execute(pool)
|
||||
.execute(&mut *tx)
|
||||
.await?;
|
||||
debug!(
|
||||
"Deleted previous replaceable event for pubkey: {}, kind: {}",
|
||||
@@ -351,7 +352,7 @@ impl NostrEventExt for NostrEvent {
|
||||
.bind(self.kind)
|
||||
.bind(&d_tag)
|
||||
.bind(self.created_at as i64)
|
||||
.fetch_optional(pool)
|
||||
.fetch_optional(&mut *tx)
|
||||
.await?;
|
||||
if let Some(_) = result {
|
||||
debug!(
|
||||
@@ -365,7 +366,7 @@ impl NostrEventExt for NostrEvent {
|
||||
.bind(&self.pubkey)
|
||||
.bind(self.kind)
|
||||
.bind(&d_tag)
|
||||
.fetch_optional(pool)
|
||||
.fetch_optional(&mut *tx)
|
||||
.await?;
|
||||
|
||||
if let Some(prev_created_at) = created_at {
|
||||
@@ -375,7 +376,7 @@ impl NostrEventExt for NostrEvent {
|
||||
.bind(&self.pubkey)
|
||||
.bind(self.kind)
|
||||
.bind(&d_tag)
|
||||
.execute(pool)
|
||||
.execute(&mut *tx)
|
||||
.await?;
|
||||
debug!(
|
||||
"Deleted previous parameterized replaceable event for pubkey: {}, kind: {}, d_tag: {}",
|
||||
@@ -401,7 +402,7 @@ impl NostrEventExt for NostrEvent {
|
||||
sqlx::query("SELECT * FROM deleted_events WHERE event_id = ? AND pubkey = ?")
|
||||
.bind(&self.id)
|
||||
.bind(&self.pubkey)
|
||||
.fetch_optional(pool)
|
||||
.fetch_optional(&mut *tx)
|
||||
.await?;
|
||||
if let Some(_) = result {
|
||||
debug!(
|
||||
@@ -420,10 +421,26 @@ impl NostrEventExt for NostrEvent {
|
||||
.bind(&self.content)
|
||||
.bind(&self.sig)
|
||||
.bind(&d_tag)
|
||||
.execute(pool)
|
||||
.execute(&mut *tx)
|
||||
.await?;
|
||||
|
||||
for tag in &self.tags {
|
||||
if tag.len() >= 2 {
|
||||
let tag_name = &tag[0];
|
||||
let tag_value = &tag[1];
|
||||
if tag_name.len() == 1 {
|
||||
sqlx::query("INSERT INTO event_tags (event_id, tag_name, tag_value, created_at) VALUES (?, ?, ?, ?)")
|
||||
.bind(&self.id)
|
||||
.bind(tag_name)
|
||||
.bind(tag_value)
|
||||
.bind(self.created_at as i64)
|
||||
.execute(&mut *tx)
|
||||
.await?;
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
tx.commit().await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
+3
-4
@@ -91,11 +91,10 @@ impl FilterExt for Filter {
|
||||
if tag_name.starts_with('#') && !tag_values.is_empty() {
|
||||
let tag_letter = &tag_name[1..]; // 提取标签字母 (e.g., 'e', 'p', 'd')
|
||||
|
||||
// 使用 JSON 函数查询 tags 数组
|
||||
// SELECT 1 FROM json_each(tags) AS tag_arr WHERE tag_arr.value->>0 = 'p' AND tag_arr.value->>1 IN ('...', '...')
|
||||
sql.push(" AND EXISTS (SELECT 1 FROM json_each(tags) AS tag_arr WHERE json_array_length(tag_arr.value) > 1 AND json_extract(tag_arr.value, '$[0]') = ");
|
||||
// 使用 event_tags 表查询
|
||||
sql.push(" AND EXISTS (SELECT 1 FROM event_tags WHERE event_id = events.id AND tag_name = ");
|
||||
sql.push_bind(tag_letter);
|
||||
sql.push(" AND json_extract(tag_arr.value, '$[1]') IN (");
|
||||
sql.push(" AND tag_value IN (");
|
||||
let mut separated = sql.separated(",");
|
||||
for value in tag_values {
|
||||
separated.push_bind(value);
|
||||
|
||||
Reference in New Issue
Block a user