From 2a8e7cbe94da4cc9d3d43bb4220cb1002a7cab51 Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Tue, 30 Dec 2025 11:42:57 -0500 Subject: [PATCH 01/63] Fixes duplicated results --- .../nip01Core/store/sqlite/QueryAssemblerTest.kt | 16 +++++++++------- .../nip01Core/store/sqlite/EventIndexesModule.kt | 2 +- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryAssemblerTest.kt b/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryAssemblerTest.kt index 2a3983a8d..fe740787c 100644 --- a/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryAssemblerTest.kt +++ b/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryAssemblerTest.kt @@ -84,12 +84,14 @@ class QueryAssemblerTest { """ SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers INNER JOIN ( - SELECT event_tags.event_header_row_id as row_id FROM event_tags INNER JOIN event_headers ON event_headers.row_id = event_tags.event_header_row_id WHERE (event_headers.created_at >= "1750889190") AND (event_tags.tag_hash = "2657743813502222172") AND (event_headers.kind = "5") AND (event_headers.pubkey = "7c5eb72a4584fdaaeaa145b25c92ea9917704224951219dbd43acef9e91fb88d") + SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags INNER JOIN event_headers ON event_headers.row_id = event_tags.event_header_row_id WHERE (event_headers.created_at >= "1750889190") AND (event_tags.tag_hash = "2657743813502222172") AND (event_headers.kind = "5") AND (event_headers.pubkey = "7c5eb72a4584fdaaeaa145b25c92ea9917704224951219dbd43acef9e91fb88d") ) AS filtered ON event_headers.row_id = filtered.row_id ORDER BY created_at DESC, id - ├── SEARCH event_tags USING COVERING INDEX query_by_tags_hash (tag_hash=?) - ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) + ├── CO-ROUTINE filtered + │ ├── SEARCH event_tags USING COVERING INDEX query_by_tags_hash (tag_hash=?) + │ └── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) + ├── SCAN filtered ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) └── USE TEMP B-TREE FOR ORDER BY """.trimIndent(), @@ -278,7 +280,7 @@ class QueryAssemblerTest { """ SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers INNER JOIN ( - SELECT event_tags.event_header_row_id as row_id FROM event_tags INNER JOIN event_headers ON event_headers.row_id = event_tags.event_header_row_id WHERE event_tags.tag_hash = "-4551135004136952885" ORDER BY event_headers.created_at DESC, event_headers.id ASC LIMIT 30 + SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags INNER JOIN event_headers ON event_headers.row_id = event_tags.event_header_row_id WHERE event_tags.tag_hash = "-4551135004136952885" ORDER BY event_headers.created_at DESC, event_headers.id ASC LIMIT 30 ) AS filtered ON event_headers.row_id = filtered.row_id ORDER BY created_at DESC, id @@ -313,7 +315,7 @@ class QueryAssemblerTest { """ SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers INNER JOIN ( - SELECT event_tags.event_header_row_id as row_id FROM event_tags INNER JOIN event_headers ON event_headers.row_id = event_tags.event_header_row_id WHERE (event_tags.tag_hash = "-4551135004136952885") AND (event_headers.kind = "3") ORDER BY event_headers.created_at DESC, event_headers.id ASC LIMIT 30 + SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags INNER JOIN event_headers ON event_headers.row_id = event_tags.event_header_row_id WHERE (event_tags.tag_hash = "-4551135004136952885") AND (event_headers.kind = "3") ORDER BY event_headers.created_at DESC, event_headers.id ASC LIMIT 30 ) AS filtered ON event_headers.row_id = filtered.row_id ORDER BY created_at DESC, id @@ -345,7 +347,7 @@ class QueryAssemblerTest { """ SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers INNER JOIN ( - SELECT event_tags.event_header_row_id as row_id FROM event_tags INNER JOIN event_headers ON event_headers.row_id = event_tags.event_header_row_id WHERE (event_tags.tag_hash = "-4551135004136952885") AND (event_headers.pubkey = "7c5eb72a4584fdaaeaa145b25c92ea9917704224951219dbd43acef9e91fb88d") ORDER BY event_headers.created_at DESC, event_headers.id ASC LIMIT 30 + SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags INNER JOIN event_headers ON event_headers.row_id = event_tags.event_header_row_id WHERE (event_tags.tag_hash = "-4551135004136952885") AND (event_headers.pubkey = "7c5eb72a4584fdaaeaa145b25c92ea9917704224951219dbd43acef9e91fb88d") ORDER BY event_headers.created_at DESC, event_headers.id ASC LIMIT 30 ) AS filtered ON event_headers.row_id = filtered.row_id ORDER BY created_at DESC, id @@ -381,7 +383,7 @@ class QueryAssemblerTest { """ SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers INNER JOIN ( - SELECT event_tags.event_header_row_id as row_id FROM event_tags INNER JOIN event_tags as event_tagst ON event_tagst.event_header_row_id = event_tags.event_header_row_id INNER JOIN event_headers ON event_headers.row_id = event_tags.event_header_row_id WHERE (event_tags.tag_hash = "-4551135004136952885") AND (event_tagst.tag_hash = "-6379614208644810021") AND (event_headers.kind = "1") ORDER BY event_headers.created_at DESC, event_headers.id ASC LIMIT 30 + SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags INNER JOIN event_tags as event_tagst ON event_tagst.event_header_row_id = event_tags.event_header_row_id INNER JOIN event_headers ON event_headers.row_id = event_tags.event_header_row_id WHERE (event_tags.tag_hash = "-4551135004136952885") AND (event_tagst.tag_hash = "-6379614208644810021") AND (event_headers.kind = "1") ORDER BY event_headers.created_at DESC, event_headers.id ASC LIMIT 30 ) AS filtered ON event_headers.row_id = filtered.row_id ORDER BY created_at DESC, id diff --git a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/EventIndexesModule.kt b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/EventIndexesModule.kt index 10fcf8301..ccc1051aa 100644 --- a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/EventIndexesModule.kt +++ b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/EventIndexesModule.kt @@ -466,7 +466,7 @@ class EventIndexesModule( buildString { // always do tags if there are any if (nonDTags.isNotEmpty()) { - append("SELECT event_tags.event_header_row_id as row_id FROM event_tags ") + append("SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags ") // it's quite rare to have 2 tags in the filter, but possible nonDTags.keys.forEachIndexed { index, tagName -> From 333285747b7dbaf4adeb492e441e0de68e27bc31 Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Tue, 30 Dec 2025 12:06:22 -0500 Subject: [PATCH 02/63] Migrates to using indexes instead tagNames to avoid non-ASCII chars reaching the DB --- .../quartz/nip01Core/store/sqlite/QueryAssemblerTest.kt | 4 ++-- .../quartz/nip01Core/store/sqlite/EventIndexesModule.kt | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryAssemblerTest.kt b/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryAssemblerTest.kt index fe740787c..c84fc1848 100644 --- a/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryAssemblerTest.kt +++ b/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryAssemblerTest.kt @@ -383,14 +383,14 @@ class QueryAssemblerTest { """ SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers INNER JOIN ( - SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags INNER JOIN event_tags as event_tagst ON event_tagst.event_header_row_id = event_tags.event_header_row_id INNER JOIN event_headers ON event_headers.row_id = event_tags.event_header_row_id WHERE (event_tags.tag_hash = "-4551135004136952885") AND (event_tagst.tag_hash = "-6379614208644810021") AND (event_headers.kind = "1") ORDER BY event_headers.created_at DESC, event_headers.id ASC LIMIT 30 + SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags INNER JOIN event_tags as event_tagsIn1 ON event_tagsIn1.event_header_row_id = event_tags.event_header_row_id INNER JOIN event_headers ON event_headers.row_id = event_tags.event_header_row_id WHERE (event_tags.tag_hash = "-4551135004136952885") AND (event_tagsIn1.tag_hash = "-6379614208644810021") AND (event_headers.kind = "1") ORDER BY event_headers.created_at DESC, event_headers.id ASC LIMIT 30 ) AS filtered ON event_headers.row_id = filtered.row_id ORDER BY created_at DESC, id ├── CO-ROUTINE filtered │ ├── SEARCH event_tags USING COVERING INDEX query_by_tags_hash (tag_hash=?) │ ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) - │ ├── SEARCH event_tagst USING COVERING INDEX query_by_tags_hash (tag_hash=? AND event_header_row_id=?) + │ ├── SEARCH event_tagsIn1 USING COVERING INDEX query_by_tags_hash (tag_hash=? AND event_header_row_id=?) │ └── USE TEMP B-TREE FOR ORDER BY ├── SCAN filtered ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) diff --git a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/EventIndexesModule.kt b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/EventIndexesModule.kt index ccc1051aa..c2b28d739 100644 --- a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/EventIndexesModule.kt +++ b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/EventIndexesModule.kt @@ -471,7 +471,7 @@ class EventIndexesModule( // it's quite rare to have 2 tags in the filter, but possible nonDTags.keys.forEachIndexed { index, tagName -> if (index > 0) { - append("INNER JOIN event_tags as event_tags$tagName ON event_tags$tagName.event_header_row_id = event_tags.event_header_row_id ") + append("INNER JOIN event_tags as event_tagsIn$index ON event_tagsIn$index.event_header_row_id = event_tags.event_header_row_id ") } else { defaultTagKey = tagName } @@ -512,7 +512,7 @@ class EventIndexesModule( if (defaultTagKey == null || defaultTagKey == tagName) { "event_tags.tag_hash" } else { - "event_tags$tagName.tag_hash" + "event_tagsIn$index.tag_hash" } equalsOrIn( From df97b7c4447d615b14056effd6b24a1c5c0d351c Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Tue, 30 Dec 2025 12:09:05 -0500 Subject: [PATCH 03/63] Improves efficiency of the filter class for matching and checking errors --- .../quartz/nip01Core/relay/filters/Filter.kt | 17 ++++++++++------- .../nip01Core/relay/filters/FilterMatcher.kt | 4 +++- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/filters/Filter.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/filters/Filter.kt index a34cd01fb..f4d1f5aad 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/filters/Filter.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/filters/Filter.kt @@ -89,14 +89,17 @@ class Filter( if (it.length != 64) Log.e("FilterError", "Invalid author length $it on ${toJson()}") } // tests common tags. - tags?.get("p")?.forEach { - if (it.length != 64) Log.e("FilterError", "Invalid p-tag length $it on ${toJson()}") + if (tags != null) { + tags["p"]?.forEach { + if (it.length != 64) Log.e("FilterError", "Invalid p-tag length $it on ${toJson()}") + } + tags["e"]?.forEach { + if (it.length != 64) Log.e("FilterError", "Invalid e-tag length $it on ${toJson()}") + } + tags["a"]?.forEach { + if (Address.parse(it) == null) Log.e("FilterError", "Invalid a-tag $it on ${toJson()}") + } } - tags?.get("e")?.forEach { - if (it.length != 64) Log.e("FilterError", "Invalid e-tag length $it on ${toJson()}") - } - tags?.get("a")?.forEach { - if (Address.parse(it) == null) Log.e("FilterError", "Invalid a-tag $it on ${toJson()}") } } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/filters/FilterMatcher.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/filters/FilterMatcher.kt index 1367984ee..7c7a579c2 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/filters/FilterMatcher.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/filters/FilterMatcher.kt @@ -36,7 +36,9 @@ object FilterMatcher { if (kinds?.contains(event.kind) == false) return false if (authors?.contains(event.pubKey) == false) return false tags?.forEach { tag -> - if (!event.tags.any { it.first() == tag.key && it[1] in tag.value }) return false + val valueSet = tag.value.toSet() + // AND between keys, OR between values + if (!event.tags.any { it.size > 1 && it[0] == tag.key && it[1] in valueSet }) return false } if (event.createdAt !in (since ?: Long.MIN_VALUE)..(until ?: Long.MAX_VALUE)) { return false From c3d741ebd14b4b00f86ec75a989b1d3d99fbc856 Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Tue, 30 Dec 2025 12:29:04 -0500 Subject: [PATCH 04/63] Implements AND queries for tags: https://github.com/nostr-protocol/nips/pull/1365 --- .../store/sqlite/FilterMatcherTest.kt | 173 ++++++++++++++++++ .../store/sqlite/QueryAssemblerTest.kt | 23 +++ .../store/sqlite/EventIndexesModule.kt | 57 +++++- .../quartz/nip01Core/relay/filters/Filter.kt | 17 +- .../nip01Core/relay/filters/FilterMatcher.kt | 15 ++ .../relay/filters/FilterMatcherTest.kt | 149 +++++++++++++++ .../relay/filters/FilterDeserializer.kt | 13 +- .../relay/filters/FilterSerializer.kt | 10 + 8 files changed, 442 insertions(+), 15 deletions(-) create mode 100644 quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/FilterMatcherTest.kt create mode 100644 quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip01Core/relay/filters/FilterMatcherTest.kt diff --git a/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/FilterMatcherTest.kt b/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/FilterMatcherTest.kt new file mode 100644 index 000000000..22f3b5c17 --- /dev/null +++ b/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/FilterMatcherTest.kt @@ -0,0 +1,173 @@ +/** + * Copyright (c) 2025 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip01Core.store.sqlite + +import android.content.Context +import androidx.test.core.app.ApplicationProvider +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter +import org.junit.After +import org.junit.Before +import org.junit.Test + +class FilterMatcherTest { + private lateinit var db: EventStore + + @Before + fun setup() { + val context = ApplicationProvider.getApplicationContext() + db = EventStore(context, null) + } + + @After + fun tearDown() { + db.close() + } + + val id = "98b574c3527f0ffb30b7271084e3f07480733c7289f8de424d29eae82e36c758" + val pubkey = "46fcbe3065eaf1ae7811465924e48923363ff3f526bd6f73d7c184b16bd8ce4d" + val createdAt: Long = 1683596206 + val kind = 1 + + val pTag1 = "22aa81510ee63fe2b16cae16e0921f78e9ba9882e2868e7e63ad6d08ae9b5954" + val pTag2 = "3f770d65d3a764a9c5cb503ae123e62ec7598ad035d836e2a810f3877a745b24" + val pTag3 = "ec4d241c334311b3a304433ee3442be29d0e88e7ec19b85edf2bba29b93565e2" + val pTag4 = "0fe0b18b4dbf0e0aa40fcd47209b2a49b3431fc453b460efcf45ca0bd16bd6ac" + val pTag5 = "8c0da4862130283ff9e67d889df264177a508974e2feb96de139804ea66d6168" + val pTag6 = "63fe6318dc58583cfe16810f86dd09e18bfd76aabc24a0081ce2856f330504ed" + val pTag7 = "4523be58d395b1b196a9b8c82b038b6895cb02b683d0c253a955068dba1facd0" + val pTag8 = "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + + val rootETag = "27ac621d7dc4a932e1a79f984308e7d20656dd6fddb2ce9cdfcb6a67b9a7bcc3" + val replyETag = "be7245af96210a0dd048cab4ad38e52dbd6c09a53ea21a7edb6be8898e5727cc" + + val note = + Event( + id, + pubkey, + createdAt, + kind, + arrayOf( + arrayOf("e", rootETag, "", "root"), + arrayOf("e", replyETag, "", "reply"), + arrayOf("p", pTag1), + arrayOf("p", pTag1), + arrayOf("p", pTag2), + arrayOf("p", pTag3), + arrayOf("p", pTag4), + arrayOf("p", pTag5), + arrayOf("p", pTag6), + arrayOf("p", pTag7), + arrayOf("p", pTag8), + ), + "Astral:\n\nhttps://void.cat/d/A5Fba5B1bcxwEmeyoD9nBs.webp\n\nIris:\n\nhttps://void.cat/d/44hTcVvhRps6xYYs99QsqA.webp\n\nSnort:\n\nhttps://void.cat/d/4nJD5TRePuQChM5tzteYbU.webp\n\nAmethyst agrees with Astral which I suspect are both wrong. nostr:npub13sx6fp3pxq5rl70x0kyfmunyzaa9pzt5utltjm0p8xqyafndv95q3saapa nostr:npub1v0lxxxxutpvrelsksy8cdhgfux9l6a42hsj2qzquu2zk7vc9qnkszrqj49 nostr:npub1g53mukxnjkcmr94fhryzkqutdz2ukq4ks0gvy5af25rgmwsl4ngq43drvk nostr:npub1gcxzte5zlkncx26j68ez60fzkvtkm9e0vrwdcvsjakxf9mu9qewqlfnj5z ", + "4aa5264965018fa12a326686ad3d3bd8beae3218dcc83689b19ca1e6baeb791531943c15363aa6707c7c0c8b2d601deca1f20c32078b2872d356cdca03b04cce", + ) + + @Test + fun matchIds() { + db.insert(note) + + db.assertQuery(note, Filter(ids = listOf(id))) + db.assertQuery(note, Filter(ids = listOf(id, rootETag))) + db.assertQuery(null, Filter(ids = listOf(rootETag))) + } + + @Test + fun matchPubkeys() { + db.insert(note) + + db.assertQuery(note, Filter(authors = listOf(pubkey))) + db.assertQuery(note, Filter(authors = listOf(pubkey, rootETag))) + db.assertQuery(null, Filter(authors = listOf(rootETag))) + } + + @Test + fun matchTags() { + db.insert(note) + + db.assertQuery(note, Filter(tags = mapOf("p" to listOf(pTag1)))) + db.assertQuery(note, Filter(tags = mapOf("p" to listOf(pTag1, pTag2, pTag3)))) + db.assertQuery(note, Filter(tags = mapOf("p" to listOf(pTag1, id)))) + db.assertQuery(null, Filter(tags = mapOf("p" to listOf(id)))) + } + + @Test + fun matchDualTags() { + db.insert(note) + + db.assertQuery(note, Filter(tags = mapOf("p" to listOf(pTag1), "e" to listOf(rootETag)))) + db.assertQuery(note, Filter(tags = mapOf("p" to listOf(pTag1, pTag2, pTag3), "e" to listOf(rootETag, replyETag)))) + db.assertQuery(note, Filter(tags = mapOf("p" to listOf(pTag1, id), "e" to listOf(rootETag, replyETag)))) + db.assertQuery(note, Filter(tags = mapOf("p" to listOf(pTag1, id), "e" to listOf(rootETag, pubkey)))) + db.assertQuery(null, Filter(tags = mapOf("p" to listOf(pTag1, id), "e" to listOf(id, pubkey)))) + db.assertQuery(null, Filter(tags = mapOf("p" to listOf(id), "e" to listOf(rootETag)))) + } + + @Test + fun matchAllTags() { + db.insert(note) + + db.assertQuery(note, Filter(tagsAll = mapOf("p" to listOf(pTag1)))) + db.assertQuery(note, Filter(tagsAll = mapOf("p" to listOf(pTag1, pTag2, pTag3)))) + db.assertQuery(null, Filter(tagsAll = mapOf("p" to listOf(pTag1, id)))) + db.assertQuery(null, Filter(tagsAll = mapOf("p" to listOf(id)))) + } + + @Test + fun matchDualAllTags() { + db.insert(note) + + db.assertQuery(note, Filter(tagsAll = mapOf("p" to listOf(pTag1), "e" to listOf(rootETag)))) + db.assertQuery(note, Filter(tagsAll = mapOf("p" to listOf(pTag1, pTag2, pTag3), "e" to listOf(rootETag, replyETag)))) + db.assertQuery(null, Filter(tagsAll = mapOf("p" to listOf(pTag1, id), "e" to listOf(rootETag, replyETag)))) + db.assertQuery(null, Filter(tagsAll = mapOf("p" to listOf(pTag1, id), "e" to listOf(rootETag, pubkey)))) + db.assertQuery(null, Filter(tagsAll = mapOf("p" to listOf(pTag1, id), "e" to listOf(id, pubkey)))) + db.assertQuery(null, Filter(tagsAll = mapOf("p" to listOf(id), "e" to listOf(rootETag)))) + } + + @Test + fun matchKinds() { + db.insert(note) + + db.assertQuery(note, Filter(kinds = listOf(kind))) + db.assertQuery(note, Filter(kinds = listOf(kind, 1221))) + db.assertQuery(null, Filter(kinds = listOf(1221))) + } + + @Test + fun matchSince() { + db.insert(note) + + db.assertQuery(note, Filter(since = createdAt)) + db.assertQuery(note, Filter(since = createdAt - 1)) + db.assertQuery(null, Filter(since = createdAt + 1)) + } + + @Test + fun matchUntil() { + db.insert(note) + + db.assertQuery(note, Filter(until = createdAt)) + db.assertQuery(note, Filter(until = createdAt + 1)) + db.assertQuery(null, Filter(until = createdAt - 1)) + } +} diff --git a/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryAssemblerTest.kt b/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryAssemblerTest.kt index c84fc1848..b972beae0 100644 --- a/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryAssemblerTest.kt +++ b/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryAssemblerTest.kt @@ -479,4 +479,27 @@ class QueryAssemblerTest { sql, ) } + + @Test + fun testAllTag() { + val sql = explain(Filter(tagsAll = mapOf("p" to listOf(key1, key2)))) + println(sql) + TestCase.assertEquals( + """ + SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers + INNER JOIN ( + SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags INNER JOIN event_tags as event_tagsAll0_1 ON event_tagsAll0_1.event_header_row_id = event_tags.event_header_row_id WHERE (event_tags.tag_hash = "884286737453847614") AND (event_tagsAll0_1.tag_hash = "-4988851810256311323") + ) AS filtered + ON event_headers.row_id = filtered.row_id + ORDER BY created_at DESC, id + ├── CO-ROUTINE filtered + │ ├── SEARCH event_tags USING COVERING INDEX query_by_tags_hash (tag_hash=?) + │ └── SEARCH event_tagsAll0_1 USING COVERING INDEX query_by_tags_hash (tag_hash=? AND event_header_row_id=?) + ├── SCAN filtered + ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) + └── USE TEMP B-TREE FOR ORDER BY + """.trimIndent(), + sql, + ) + } } diff --git a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/EventIndexesModule.kt b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/EventIndexesModule.kt index c2b28d739..9fdd08982 100644 --- a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/EventIndexesModule.kt +++ b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/EventIndexesModule.kt @@ -436,6 +436,17 @@ class EventIndexesModule( } } + sealed class TagNameForQuery { + class InTags( + val tagName: String, + ) : TagNameForQuery() + + class AllTags( + val tagName: String, + val tagValueIndex: Int, + ) : TagNameForQuery() + } + // ---------------------------- // Inner row id selections // ---------------------------- @@ -447,7 +458,9 @@ class EventIndexesModule( val mustJoinSearch = (filter.search != null) - val nonDTags = filter.tags?.filter { it.key != "d" } ?: emptyMap() + val nonDTagsIn = filter.tags?.filter { it.key != "d" } ?: emptyMap() + + val nonDTagsAll = filter.tagsAll?.filter { it.key != "d" } ?: emptyMap() val hasHeaders = with(filter) { @@ -460,20 +473,30 @@ class EventIndexesModule( (limit != null) } - var defaultTagKey: String? = null + var defaultTagKey: TagNameForQuery? = null val projection = buildString { // always do tags if there are any - if (nonDTags.isNotEmpty()) { + if (nonDTagsIn.isNotEmpty() || nonDTagsAll.isNotEmpty()) { append("SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags ") // it's quite rare to have 2 tags in the filter, but possible - nonDTags.keys.forEachIndexed { index, tagName -> - if (index > 0) { + nonDTagsIn.keys.forEachIndexed { index, tagName -> + if (defaultTagKey != null) { append("INNER JOIN event_tags as event_tagsIn$index ON event_tagsIn$index.event_header_row_id = event_tags.event_header_row_id ") } else { - defaultTagKey = tagName + defaultTagKey = TagNameForQuery.InTags(tagName) + } + } + + nonDTagsAll.keys.forEachIndexed { index, tagName -> + nonDTagsAll[tagName]!!.forEachIndexed { valueIndex, tagValue -> + if (defaultTagKey != null) { + append("INNER JOIN event_tags as event_tagsAll${index}_$valueIndex ON event_tagsAll${index}_$valueIndex.event_header_row_id = event_tags.event_header_row_id ") + } else { + defaultTagKey = TagNameForQuery.AllTags(tagName, valueIndex) + } } } @@ -506,10 +529,10 @@ class EventIndexesModule( filter.since?.let { greaterThanOrEquals("event_headers.created_at", it) } filter.until?.let { lessThanOrEquals("event_headers.created_at", it) } - // there are indexes for these, starting with tags. - nonDTags.forEach { (tagName, tagValues) -> + // it's quite rare to have 2 tags in the filter, but possible + nonDTagsIn.keys.forEachIndexed { index, tagName -> val column = - if (defaultTagKey == null || defaultTagKey == tagName) { + if (defaultTagKey == null || (defaultTagKey is TagNameForQuery.InTags && defaultTagKey.tagName == tagName)) { "event_tags.tag_hash" } else { "event_tagsIn$index.tag_hash" @@ -517,12 +540,26 @@ class EventIndexesModule( equalsOrIn( column, - tagValues.map { + nonDTagsIn[tagName]!!.map { hasher.hash(tagName, it) }, ) } + // there are indexes for these, starting with tags. + nonDTagsAll.keys.forEachIndexed { index, tagName -> + nonDTagsAll[tagName]!!.forEachIndexed { valueIndex, tagValue -> + val column = + if (defaultTagKey == null || (defaultTagKey is TagNameForQuery.AllTags && defaultTagKey.tagName == tagName && defaultTagKey.tagValueIndex == valueIndex)) { + "event_tags.tag_hash" + } else { + "event_tagsAll${index}_$valueIndex.tag_hash" + } + + equals(column, hasher.hash(tagName, tagValue)) + } + } + filter.kinds?.let { equalsOrIn("event_headers.kind", it) } filter.authors?.let { equalsOrIn("event_headers.pubkey", it) } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/filters/Filter.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/filters/Filter.kt index f4d1f5aad..2d1fb0188 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/filters/Filter.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/filters/Filter.kt @@ -48,6 +48,7 @@ class Filter( val authors: List? = null, val kinds: List? = null, val tags: Map>? = null, + val tagsAll: Map>? = null, val since: Long? = null, val until: Long? = null, val limit: Int? = null, @@ -55,18 +56,19 @@ class Filter( ) : OptimizedSerializable { fun toJson() = OptimizedJsonMapper.toJson(this) - fun match(event: Event) = FilterMatcher.match(event, ids, authors, kinds, tags, since, until) + fun match(event: Event) = FilterMatcher.match(event, ids, authors, kinds, tags, tagsAll, since, until) fun copy( ids: List? = this.ids, authors: List? = this.authors, kinds: List? = this.kinds, tags: Map>? = this.tags, + tagsAll: Map>? = this.tagsAll, since: Long? = this.since, until: Long? = this.until, limit: Int? = this.limit, search: String? = this.search, - ) = Filter(ids, authors, kinds, tags, since, until, limit, search) + ) = Filter(ids, authors, kinds, tags, tagsAll, since, until, limit, search) /** * Returns true if this filter contains any non-null and non-empty criteria. @@ -76,6 +78,7 @@ class Filter( (authors != null && authors.isNotEmpty()) || (kinds != null && kinds.isNotEmpty()) || (tags != null && tags.isNotEmpty() && tags.values.all { it.isNotEmpty() }) || + (tagsAll != null && tagsAll.isNotEmpty() && tagsAll.values.all { it.isNotEmpty() }) || (since != null) || (until != null) || (limit != null) || @@ -100,6 +103,16 @@ class Filter( if (Address.parse(it) == null) Log.e("FilterError", "Invalid a-tag $it on ${toJson()}") } } + if (tagsAll != null) { + tagsAll["p"]?.forEach { + if (it.length != 64) Log.e("FilterError", "Invalid p-tag length $it on ${toJson()}") + } + tagsAll["e"]?.forEach { + if (it.length != 64) Log.e("FilterError", "Invalid e-tag length $it on ${toJson()}") + } + tagsAll["a"]?.forEach { + if (Address.parse(it) == null) Log.e("FilterError", "Invalid a-tag $it on ${toJson()}") + } } } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/filters/FilterMatcher.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/filters/FilterMatcher.kt index 7c7a579c2..0539a9d76 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/filters/FilterMatcher.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/filters/FilterMatcher.kt @@ -29,6 +29,7 @@ object FilterMatcher { authors: List? = null, kinds: List? = null, tags: Map>? = null, + tagsAll: Map>? = null, since: Long? = null, until: Long? = null, ): Boolean { @@ -40,6 +41,20 @@ object FilterMatcher { // AND between keys, OR between values if (!event.tags.any { it.size > 1 && it[0] == tag.key && it[1] in valueSet }) return false } + tagsAll?.forEach { tag -> + val eventTagValueSet = + event.tags.mapNotNullTo(mutableSetOf()) { + if (it.size > 1 && it[0] == tag.key) { + it[1] + } else { + null + } + } + // AND between keys, AND between values + for (tagValue in tag.value) { + if (tagValue !in eventTagValueSet) return false + } + } if (event.createdAt !in (since ?: Long.MIN_VALUE)..(until ?: Long.MAX_VALUE)) { return false } diff --git a/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip01Core/relay/filters/FilterMatcherTest.kt b/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip01Core/relay/filters/FilterMatcherTest.kt new file mode 100644 index 000000000..ea697b2f0 --- /dev/null +++ b/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip01Core/relay/filters/FilterMatcherTest.kt @@ -0,0 +1,149 @@ +/** + * Copyright (c) 2025 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip01Core.relay.filters + +import com.vitorpamplona.quartz.nip01Core.core.Event +import kotlin.test.Test +import kotlin.test.assertFalse +import kotlin.test.assertTrue + +class FilterMatcherTest { + val id = "98b574c3527f0ffb30b7271084e3f07480733c7289f8de424d29eae82e36c758" + val pubkey = "46fcbe3065eaf1ae7811465924e48923363ff3f526bd6f73d7c184b16bd8ce4d" + val createdAt: Long = 1683596206 + val kind = 1 + + val pTag1 = "22aa81510ee63fe2b16cae16e0921f78e9ba9882e2868e7e63ad6d08ae9b5954" + val pTag2 = "3f770d65d3a764a9c5cb503ae123e62ec7598ad035d836e2a810f3877a745b24" + val pTag3 = "ec4d241c334311b3a304433ee3442be29d0e88e7ec19b85edf2bba29b93565e2" + val pTag4 = "0fe0b18b4dbf0e0aa40fcd47209b2a49b3431fc453b460efcf45ca0bd16bd6ac" + val pTag5 = "8c0da4862130283ff9e67d889df264177a508974e2feb96de139804ea66d6168" + val pTag6 = "63fe6318dc58583cfe16810f86dd09e18bfd76aabc24a0081ce2856f330504ed" + val pTag7 = "4523be58d395b1b196a9b8c82b038b6895cb02b683d0c253a955068dba1facd0" + val pTag8 = "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c" + + val rootETag = "27ac621d7dc4a932e1a79f984308e7d20656dd6fddb2ce9cdfcb6a67b9a7bcc3" + val replyETag = "be7245af96210a0dd048cab4ad38e52dbd6c09a53ea21a7edb6be8898e5727cc" + + val note = + Event( + id, + pubkey, + createdAt, + kind, + arrayOf( + arrayOf("e", rootETag, "", "root"), + arrayOf("e", replyETag, "", "reply"), + arrayOf("p", pTag1), + arrayOf("p", pTag1), + arrayOf("p", pTag2), + arrayOf("p", pTag3), + arrayOf("p", pTag4), + arrayOf("p", pTag5), + arrayOf("p", pTag6), + arrayOf("p", pTag7), + arrayOf("p", pTag8), + ), + "Astral:\n\nhttps://void.cat/d/A5Fba5B1bcxwEmeyoD9nBs.webp\n\nIris:\n\nhttps://void.cat/d/44hTcVvhRps6xYYs99QsqA.webp\n\nSnort:\n\nhttps://void.cat/d/4nJD5TRePuQChM5tzteYbU.webp\n\nAmethyst agrees with Astral which I suspect are both wrong. nostr:npub13sx6fp3pxq5rl70x0kyfmunyzaa9pzt5utltjm0p8xqyafndv95q3saapa nostr:npub1v0lxxxxutpvrelsksy8cdhgfux9l6a42hsj2qzquu2zk7vc9qnkszrqj49 nostr:npub1g53mukxnjkcmr94fhryzkqutdz2ukq4ks0gvy5af25rgmwsl4ngq43drvk nostr:npub1gcxzte5zlkncx26j68ez60fzkvtkm9e0vrwdcvsjakxf9mu9qewqlfnj5z ", + "4aa5264965018fa12a326686ad3d3bd8beae3218dcc83689b19ca1e6baeb791531943c15363aa6707c7c0c8b2d601deca1f20c32078b2872d356cdca03b04cce", + ) + + @Test + fun matchIds() { + assertTrue(note, Filter(ids = listOf(id))) + assertTrue(note, Filter(ids = listOf(id, rootETag))) + assertFalse(note, Filter(ids = listOf(rootETag))) + } + + @Test + fun matchPubkeys() { + assertTrue(note, Filter(authors = listOf(pubkey))) + assertTrue(note, Filter(authors = listOf(pubkey, rootETag))) + assertFalse(note, Filter(authors = listOf(rootETag))) + } + + @Test + fun matchTags() { + assertTrue(note, Filter(tags = mapOf("p" to listOf(pTag1)))) + assertTrue(note, Filter(tags = mapOf("p" to listOf(pTag1, pTag2, pTag3)))) + assertTrue(note, Filter(tags = mapOf("p" to listOf(pTag1, id)))) + assertFalse(note, Filter(tags = mapOf("p" to listOf(id)))) + } + + @Test + fun matchDualTags() { + assertTrue(note, Filter(tags = mapOf("p" to listOf(pTag1), "e" to listOf(rootETag)))) + assertTrue(note, Filter(tags = mapOf("p" to listOf(pTag1, pTag2, pTag3), "e" to listOf(rootETag, replyETag)))) + assertTrue(note, Filter(tags = mapOf("p" to listOf(pTag1, id), "e" to listOf(rootETag, replyETag)))) + assertTrue(note, Filter(tags = mapOf("p" to listOf(pTag1, id), "e" to listOf(rootETag, pubkey)))) + assertFalse(note, Filter(tags = mapOf("p" to listOf(pTag1, id), "e" to listOf(id, pubkey)))) + assertFalse(note, Filter(tags = mapOf("p" to listOf(id), "e" to listOf(rootETag)))) + } + + @Test + fun matchAllTags() { + assertTrue(note, Filter(tagsAll = mapOf("p" to listOf(pTag1, pTag2, pTag3)))) + assertTrue(note, Filter(tagsAll = mapOf("p" to listOf(pTag1)))) + assertFalse(note, Filter(tagsAll = mapOf("p" to listOf(pTag1, id)))) + assertFalse(note, Filter(tagsAll = mapOf("p" to listOf(id)))) + } + + @Test + fun matchDualAllTags() { + assertTrue(note, Filter(tagsAll = mapOf("p" to listOf(pTag1), "e" to listOf(rootETag)))) + assertTrue(note, Filter(tagsAll = mapOf("p" to listOf(pTag1, pTag2, pTag3), "e" to listOf(rootETag, replyETag)))) + assertFalse(note, Filter(tagsAll = mapOf("p" to listOf(pTag1, id), "e" to listOf(rootETag, replyETag)))) + assertFalse(note, Filter(tagsAll = mapOf("p" to listOf(pTag1, id), "e" to listOf(rootETag, pubkey)))) + assertFalse(note, Filter(tagsAll = mapOf("p" to listOf(pTag1, id), "e" to listOf(id, pubkey)))) + assertFalse(note, Filter(tagsAll = mapOf("p" to listOf(id), "e" to listOf(rootETag)))) + } + + @Test + fun matchKinds() { + assertTrue(note, Filter(kinds = listOf(kind))) + assertTrue(note, Filter(kinds = listOf(kind, 1221))) + assertFalse(note, Filter(kinds = listOf(1221))) + } + + @Test + fun matchSince() { + assertTrue(note, Filter(since = createdAt)) + assertTrue(note, Filter(since = createdAt - 1)) + assertFalse(note, Filter(since = createdAt + 1)) + } + + @Test + fun matchUntil() { + assertTrue(note, Filter(until = createdAt)) + assertTrue(note, Filter(until = createdAt + 1)) + assertFalse(note, Filter(until = createdAt - 1)) + } + + fun assertTrue( + event: Event, + filter: Filter, + ) = assertTrue(filter.match(event)) + + fun assertFalse( + event: Event, + filter: Filter, + ) = assertFalse(filter.match(event)) +} diff --git a/quartz/src/jvmAndroid/kotlin/com/vitorpamplona/quartz/nip01Core/relay/filters/FilterDeserializer.kt b/quartz/src/jvmAndroid/kotlin/com/vitorpamplona/quartz/nip01Core/relay/filters/FilterDeserializer.kt index 7b7cbeeca..556dda5de 100644 --- a/quartz/src/jvmAndroid/kotlin/com/vitorpamplona/quartz/nip01Core/relay/filters/FilterDeserializer.kt +++ b/quartz/src/jvmAndroid/kotlin/com/vitorpamplona/quartz/nip01Core/relay/filters/FilterDeserializer.kt @@ -38,10 +38,16 @@ class FilterDeserializer : StdDeserializer(Filter::class.java) { class ManualFilterDeserializer { companion object { fun fromJson(jsonObject: ObjectNode): Filter { - val tags = mutableListOf() + val tagsIn = mutableListOf() jsonObject.fieldNames().forEach { if (it.startsWith("#")) { - tags.add(it.substring(1)) + tagsIn.add(it.substring(1)) + } + } + val tagsAll = mutableListOf() + jsonObject.fieldNames().forEach { + if (it.startsWith("&")) { + tagsAll.add(it.substring(1)) } } @@ -49,7 +55,8 @@ class ManualFilterDeserializer { ids = jsonObject.get("ids").mapNotNull { it.asTextOrNull() }, authors = jsonObject.get("authors").mapNotNull { it.asTextOrNull() }, kinds = jsonObject.get("kinds").mapNotNull { it.asIntOrNull() }, - tags = tags.associateWith { jsonObject.get(it).mapNotNull { it.asTextOrNull() } }, + tags = tagsIn.associateWith { jsonObject.get(it).mapNotNull { it.asTextOrNull() } }, + tagsAll = tagsAll.associateWith { jsonObject.get(it).mapNotNull { it.asTextOrNull() } }, since = jsonObject.get("since").asLongOrNull(), until = jsonObject.get("until").asLongOrNull(), limit = jsonObject.get("limit").asIntOrNull(), diff --git a/quartz/src/jvmAndroid/kotlin/com/vitorpamplona/quartz/nip01Core/relay/filters/FilterSerializer.kt b/quartz/src/jvmAndroid/kotlin/com/vitorpamplona/quartz/nip01Core/relay/filters/FilterSerializer.kt index afd06b36b..47fdcc674 100644 --- a/quartz/src/jvmAndroid/kotlin/com/vitorpamplona/quartz/nip01Core/relay/filters/FilterSerializer.kt +++ b/quartz/src/jvmAndroid/kotlin/com/vitorpamplona/quartz/nip01Core/relay/filters/FilterSerializer.kt @@ -66,6 +66,16 @@ class FilterSerializer : StdSerializer(Filter::class.java) { } } + filter.tagsAll?.run { + entries.forEach { kv -> + gen.writeArrayFieldStart("&${kv.key}") + for (i in kv.value.indices) { + gen.writeString(kv.value[i]) + } + gen.writeEndArray() + } + } + filter.since?.run { gen.writeNumberField("since", this) } filter.until?.run { gen.writeNumberField("until", this) } filter.limit?.run { gen.writeNumberField("limit", this) } From 5eb9d230e26065cb6f88cc095cc53ee14e18e417 Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Tue, 30 Dec 2025 13:00:03 -0500 Subject: [PATCH 05/63] Moves current test to a better name of Notifications Adds a Followers test --- .../store/sqlite/QueryAssemblerTest.kt | 35 +++++++++++++++++-- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryAssemblerTest.kt b/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryAssemblerTest.kt index b972beae0..49c9cf12a 100644 --- a/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryAssemblerTest.kt +++ b/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryAssemblerTest.kt @@ -77,9 +77,6 @@ class QueryAssemblerTest { since = 1750889190, ), ) - - println(query) - TestCase.assertEquals( """ SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers @@ -267,6 +264,38 @@ class QueryAssemblerTest { @Test fun testFollowersOf() { + val sql = + explain( + listOf( + Filter( + kinds = listOf(ContactListEvent.KIND), + tags = mapOf("p" to listOf("460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c")), + limit = 30, + ), + ), + ) + TestCase.assertEquals( + """ + SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers + INNER JOIN ( + SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags INNER JOIN event_headers ON event_headers.row_id = event_tags.event_header_row_id WHERE (event_tags.tag_hash = "-4551135004136952885") AND (event_headers.kind = "3") ORDER BY event_headers.created_at DESC, event_headers.id ASC LIMIT 30 + ) AS filtered + ON event_headers.row_id = filtered.row_id + ORDER BY created_at DESC, id + ├── CO-ROUTINE filtered + │ ├── SEARCH event_tags USING COVERING INDEX query_by_tags_hash (tag_hash=?) + │ ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) + │ └── USE TEMP B-TREE FOR ORDER BY + ├── SCAN filtered + ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) + └── USE TEMP B-TREE FOR ORDER BY + """.trimIndent(), + sql, + ) + } + + @Test + fun testNotificationsOf() { val sql = explain( listOf( From 7b696f5f544026a43c0c1403cc78a8d941895f04 Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Tue, 30 Dec 2025 16:23:11 -0500 Subject: [PATCH 06/63] Adds created_at to tags to speed up tag-ordered queries --- .../nip01Core/store/sqlite/DeletionTest.kt | 4 +- .../store/sqlite/QueryAssemblerTest.kt | 49 ++++++++--------- .../store/sqlite/DeletionRequestModule.kt | 10 ++-- .../store/sqlite/EventIndexesModule.kt | 52 ++++++++++++++----- 4 files changed, 72 insertions(+), 43 deletions(-) diff --git a/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/DeletionTest.kt b/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/DeletionTest.kt index 1f7f771b3..bb35f07be 100644 --- a/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/DeletionTest.kt +++ b/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/DeletionTest.kt @@ -227,8 +227,8 @@ class DeletionTest { ON event_headers.row_id = event_tags.event_header_row_id WHERE event_tags.tag_hash IN (3221122, 223322) AND + event_tags.created_at >= 1766686500 AND event_headers.kind = 5 AND - event_headers.created_at >= 1766686500 AND event_headers.pubkey_owner_hash = 22332323 """.trimIndent() @@ -238,7 +238,7 @@ class DeletionTest { TestCase.assertEquals( """ ${sql.replace("\n","\n ")} - ├── SEARCH event_tags USING COVERING INDEX query_by_tags_hash (tag_hash=?) + ├── SEARCH event_tags USING INDEX query_by_tags_hash (tag_hash=? AND created_at>?) └── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) """.trimIndent(), explainer, diff --git a/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryAssemblerTest.kt b/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryAssemblerTest.kt index 49c9cf12a..9a6000835 100644 --- a/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryAssemblerTest.kt +++ b/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryAssemblerTest.kt @@ -31,7 +31,7 @@ import org.junit.Before import org.junit.Test class QueryAssemblerTest { - val hasher = TagNameValueHasher(0L) + val hasher = TagNameValueHasher(0) val builder = EventIndexesModule(FullTextSearchModule(), { hasher }) val key1 = "7c5eb72a4584fdaaeaa145b25c92ea9917704224951219dbd43acef9e91fb88d" @@ -81,13 +81,14 @@ class QueryAssemblerTest { """ SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers INNER JOIN ( - SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags INNER JOIN event_headers ON event_headers.row_id = event_tags.event_header_row_id WHERE (event_headers.created_at >= "1750889190") AND (event_tags.tag_hash = "2657743813502222172") AND (event_headers.kind = "5") AND (event_headers.pubkey = "7c5eb72a4584fdaaeaa145b25c92ea9917704224951219dbd43acef9e91fb88d") + SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags INNER JOIN event_headers ON event_headers.row_id = event_tags.event_header_row_id WHERE (event_tags.tag_hash = "2657743813502222172") AND (event_tags.created_at >= "1750889190") AND (event_headers.kind = "5") AND (event_headers.pubkey = "7c5eb72a4584fdaaeaa145b25c92ea9917704224951219dbd43acef9e91fb88d") ) AS filtered ON event_headers.row_id = filtered.row_id ORDER BY created_at DESC, id ├── CO-ROUTINE filtered - │ ├── SEARCH event_tags USING COVERING INDEX query_by_tags_hash (tag_hash=?) - │ └── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) + │ ├── SEARCH event_tags USING INDEX query_by_tags_hash (tag_hash=? AND created_at>?) + │ ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) + │ └── USE TEMP B-TREE FOR DISTINCT ├── SCAN filtered ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) └── USE TEMP B-TREE FOR ORDER BY @@ -278,14 +279,14 @@ class QueryAssemblerTest { """ SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers INNER JOIN ( - SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags INNER JOIN event_headers ON event_headers.row_id = event_tags.event_header_row_id WHERE (event_tags.tag_hash = "-4551135004136952885") AND (event_headers.kind = "3") ORDER BY event_headers.created_at DESC, event_headers.id ASC LIMIT 30 + SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags INNER JOIN event_headers ON event_headers.row_id = event_tags.event_header_row_id WHERE (event_tags.tag_hash = "-4551135004136952885") AND (event_headers.kind = "3") ORDER BY event_tags.created_at DESC LIMIT 30 ) AS filtered ON event_headers.row_id = filtered.row_id ORDER BY created_at DESC, id ├── CO-ROUTINE filtered - │ ├── SEARCH event_tags USING COVERING INDEX query_by_tags_hash (tag_hash=?) + │ ├── SEARCH event_tags USING INDEX query_by_tags_hash (tag_hash=?) │ ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) - │ └── USE TEMP B-TREE FOR ORDER BY + │ └── USE TEMP B-TREE FOR DISTINCT ├── SCAN filtered ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) └── USE TEMP B-TREE FOR ORDER BY @@ -309,14 +310,13 @@ class QueryAssemblerTest { """ SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers INNER JOIN ( - SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags INNER JOIN event_headers ON event_headers.row_id = event_tags.event_header_row_id WHERE event_tags.tag_hash = "-4551135004136952885" ORDER BY event_headers.created_at DESC, event_headers.id ASC LIMIT 30 + SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags WHERE event_tags.tag_hash = "-4551135004136952885" ORDER BY event_tags.created_at DESC LIMIT 30 ) AS filtered ON event_headers.row_id = filtered.row_id ORDER BY created_at DESC, id ├── CO-ROUTINE filtered - │ ├── SEARCH event_tags USING COVERING INDEX query_by_tags_hash (tag_hash=?) - │ ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) - │ └── USE TEMP B-TREE FOR ORDER BY + │ ├── SEARCH event_tags USING INDEX query_by_tags_hash (tag_hash=?) + │ └── USE TEMP B-TREE FOR DISTINCT ├── SCAN filtered ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) └── USE TEMP B-TREE FOR ORDER BY @@ -344,14 +344,14 @@ class QueryAssemblerTest { """ SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers INNER JOIN ( - SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags INNER JOIN event_headers ON event_headers.row_id = event_tags.event_header_row_id WHERE (event_tags.tag_hash = "-4551135004136952885") AND (event_headers.kind = "3") ORDER BY event_headers.created_at DESC, event_headers.id ASC LIMIT 30 + SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags INNER JOIN event_headers ON event_headers.row_id = event_tags.event_header_row_id WHERE (event_tags.tag_hash = "-4551135004136952885") AND (event_headers.kind = "3") ORDER BY event_tags.created_at DESC LIMIT 30 ) AS filtered ON event_headers.row_id = filtered.row_id ORDER BY created_at DESC, id ├── CO-ROUTINE filtered - │ ├── SEARCH event_tags USING COVERING INDEX query_by_tags_hash (tag_hash=?) + │ ├── SEARCH event_tags USING INDEX query_by_tags_hash (tag_hash=?) │ ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) - │ └── USE TEMP B-TREE FOR ORDER BY + │ └── USE TEMP B-TREE FOR DISTINCT ├── SCAN filtered ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) └── USE TEMP B-TREE FOR ORDER BY @@ -376,14 +376,14 @@ class QueryAssemblerTest { """ SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers INNER JOIN ( - SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags INNER JOIN event_headers ON event_headers.row_id = event_tags.event_header_row_id WHERE (event_tags.tag_hash = "-4551135004136952885") AND (event_headers.pubkey = "7c5eb72a4584fdaaeaa145b25c92ea9917704224951219dbd43acef9e91fb88d") ORDER BY event_headers.created_at DESC, event_headers.id ASC LIMIT 30 + SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags INNER JOIN event_headers ON event_headers.row_id = event_tags.event_header_row_id WHERE (event_tags.tag_hash = "-4551135004136952885") AND (event_headers.pubkey = "7c5eb72a4584fdaaeaa145b25c92ea9917704224951219dbd43acef9e91fb88d") ORDER BY event_tags.created_at DESC LIMIT 30 ) AS filtered ON event_headers.row_id = filtered.row_id ORDER BY created_at DESC, id ├── CO-ROUTINE filtered - │ ├── SEARCH event_tags USING COVERING INDEX query_by_tags_hash (tag_hash=?) + │ ├── SEARCH event_tags USING INDEX query_by_tags_hash (tag_hash=?) │ ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) - │ └── USE TEMP B-TREE FOR ORDER BY + │ └── USE TEMP B-TREE FOR DISTINCT ├── SCAN filtered ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) └── USE TEMP B-TREE FOR ORDER BY @@ -412,15 +412,15 @@ class QueryAssemblerTest { """ SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers INNER JOIN ( - SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags INNER JOIN event_tags as event_tagsIn1 ON event_tagsIn1.event_header_row_id = event_tags.event_header_row_id INNER JOIN event_headers ON event_headers.row_id = event_tags.event_header_row_id WHERE (event_tags.tag_hash = "-4551135004136952885") AND (event_tagsIn1.tag_hash = "-6379614208644810021") AND (event_headers.kind = "1") ORDER BY event_headers.created_at DESC, event_headers.id ASC LIMIT 30 + SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags INNER JOIN event_tags as event_tagsIn1 ON event_tagsIn1.event_header_row_id = event_tags.event_header_row_id AND event_tagsIn1.created_at = event_tags.created_at INNER JOIN event_headers ON event_headers.row_id = event_tags.event_header_row_id WHERE (event_tags.tag_hash = "-4551135004136952885") AND (event_tagsIn1.tag_hash = "-6379614208644810021") AND (event_headers.kind = "1") ORDER BY event_tags.created_at DESC LIMIT 30 ) AS filtered ON event_headers.row_id = filtered.row_id ORDER BY created_at DESC, id ├── CO-ROUTINE filtered - │ ├── SEARCH event_tags USING COVERING INDEX query_by_tags_hash (tag_hash=?) + │ ├── SEARCH event_tags USING INDEX query_by_tags_hash (tag_hash=?) │ ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) - │ ├── SEARCH event_tagsIn1 USING COVERING INDEX query_by_tags_hash (tag_hash=? AND event_header_row_id=?) - │ └── USE TEMP B-TREE FOR ORDER BY + │ ├── SEARCH event_tagsIn1 USING INDEX query_by_tags_hash (tag_hash=? AND event_header_row_id=?) + │ └── USE TEMP B-TREE FOR DISTINCT ├── SCAN filtered ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) └── USE TEMP B-TREE FOR ORDER BY @@ -517,13 +517,14 @@ class QueryAssemblerTest { """ SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers INNER JOIN ( - SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags INNER JOIN event_tags as event_tagsAll0_1 ON event_tagsAll0_1.event_header_row_id = event_tags.event_header_row_id WHERE (event_tags.tag_hash = "884286737453847614") AND (event_tagsAll0_1.tag_hash = "-4988851810256311323") + SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags INNER JOIN event_tags as event_tagsAll0_1 ON event_tagsAll0_1.event_header_row_id = event_tags.event_header_row_id AND event_tagsAll0_1.created_at = event_tags.created_at WHERE (event_tags.tag_hash = "884286737453847614") AND (event_tagsAll0_1.tag_hash = "-4988851810256311323") ) AS filtered ON event_headers.row_id = filtered.row_id ORDER BY created_at DESC, id ├── CO-ROUTINE filtered - │ ├── SEARCH event_tags USING COVERING INDEX query_by_tags_hash (tag_hash=?) - │ └── SEARCH event_tagsAll0_1 USING COVERING INDEX query_by_tags_hash (tag_hash=? AND event_header_row_id=?) + │ ├── SEARCH event_tags USING INDEX query_by_tags_hash (tag_hash=?) + │ ├── SEARCH event_tagsAll0_1 USING INDEX query_by_tags_hash (tag_hash=? AND created_at=?) + │ └── USE TEMP B-TREE FOR DISTINCT ├── SCAN filtered ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) └── USE TEMP B-TREE FOR ORDER BY diff --git a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/DeletionRequestModule.kt b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/DeletionRequestModule.kt index 32e567fd1..de7b13e59 100644 --- a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/DeletionRequestModule.kt +++ b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/DeletionRequestModule.kt @@ -43,7 +43,11 @@ class DeletionRequestModule( BEFORE INSERT ON event_headers FOR EACH ROW BEGIN - -- Check for ID-based deletion record + -- Checks if this event hasn't already been deleted. If so, reject it. + + -- Highly optimized using hash + created_at (duplicated in tags) index: + ---- Expects tag_hash to be non-existant for new events (quick exit) + ---- Expects created-at >= event's to not exist (quick exit) SELECT RAISE(ABORT, 'blocked: a deletion event exists') WHERE EXISTS ( SELECT 1 FROM event_tags @@ -51,9 +55,9 @@ class DeletionRequestModule( ON event_headers.row_id = event_tags.event_header_row_id WHERE event_tags.tag_hash IN (NEW.etag_hash, NEW.atag_hash) AND + event_tags.created_at >= NEW.created_at AND event_headers.kind = 5 AND - event_headers.pubkey_owner_hash = NEW.pubkey_owner_hash AND - event_headers.created_at >= NEW.created_at + event_headers.pubkey_owner_hash = NEW.pubkey_owner_hash ); END; """.trimIndent(), diff --git a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/EventIndexesModule.kt b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/EventIndexesModule.kt index 9fdd08982..981260c58 100644 --- a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/EventIndexesModule.kt +++ b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/EventIndexesModule.kt @@ -63,6 +63,7 @@ class EventIndexesModule( CREATE TABLE event_tags ( event_header_row_id INTEGER NOT NULL, tag_hash INTEGER NOT NULL, + created_at INTEGER NOT NULL, FOREIGN KEY (event_header_row_id) REFERENCES event_headers(row_id) ON DELETE CASCADE ) """.trimIndent(), @@ -70,12 +71,15 @@ class EventIndexesModule( db.execSQL("CREATE UNIQUE INDEX event_headers_id ON event_headers (id)") db.execSQL("CREATE INDEX query_by_kind_pubkey_dtag_idx ON event_headers (kind, pubkey, d_tag)") - db.execSQL("CREATE INDEX query_by_created_at_id ON event_headers (created_at desc, id)") + db.execSQL("CREATE INDEX query_by_created_at_id ON event_headers (created_at DESC, id)") + // need to check if this is actually needed. - db.execSQL("CREATE INDEX query_by_created_at_kind_key ON event_headers (created_at desc, kind, pubkey)") + db.execSQL("CREATE INDEX query_by_created_at_kind_key ON event_headers (created_at DESC, kind, pubkey)") db.execSQL("CREATE INDEX fk_event_tags_header_id ON event_tags (event_header_row_id)") - db.execSQL("CREATE INDEX query_by_tags_hash ON event_tags (tag_hash, event_header_row_id)") + + // This is a very slow index to build (half the insert time goes here) but it is extremely effective. + db.execSQL("CREATE INDEX query_by_tags_hash ON event_tags (tag_hash, created_at DESC)") // Prevent updates to maintain immutability db.execSQL( @@ -117,9 +121,9 @@ class EventIndexesModule( val sqlInsertTags = """ INSERT OR ROLLBACK INTO event_tags - (event_header_row_id, tag_hash) + (event_header_row_id, tag_hash, created_at) VALUES - (?,?) + (?,?,?) """.trimIndent() fun insert( @@ -177,6 +181,7 @@ class EventIndexesModule( indexableTags.forEach { stmtTags.bindLong(1, headerId) stmtTags.bindLong(2, it) + stmtTags.bindLong(3, event.createdAt) stmtTags.executeInsert() } @@ -462,6 +467,16 @@ class EventIndexesModule( val nonDTagsAll = filter.tagsAll?.filter { it.key != "d" } ?: emptyMap() + val reverseLookup = nonDTagsIn.isNotEmpty() || nonDTagsAll.isNotEmpty() + + val needHeaders = + with(filter) { + (ids != null) || + (authors != null && authors.isNotEmpty()) || + (kinds != null && kinds.isNotEmpty()) || + (tags != null && tags.containsKey("d")) + } + val hasHeaders = with(filter) { (ids != null) || @@ -478,13 +493,13 @@ class EventIndexesModule( val projection = buildString { // always do tags if there are any - if (nonDTagsIn.isNotEmpty() || nonDTagsAll.isNotEmpty()) { + if (reverseLookup) { append("SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags ") // it's quite rare to have 2 tags in the filter, but possible nonDTagsIn.keys.forEachIndexed { index, tagName -> if (defaultTagKey != null) { - append("INNER JOIN event_tags as event_tagsIn$index ON event_tagsIn$index.event_header_row_id = event_tags.event_header_row_id ") + append("INNER JOIN event_tags as event_tagsIn$index ON event_tagsIn$index.event_header_row_id = event_tags.event_header_row_id AND event_tagsIn$index.created_at = event_tags.created_at ") } else { defaultTagKey = TagNameForQuery.InTags(tagName) } @@ -493,14 +508,14 @@ class EventIndexesModule( nonDTagsAll.keys.forEachIndexed { index, tagName -> nonDTagsAll[tagName]!!.forEachIndexed { valueIndex, tagValue -> if (defaultTagKey != null) { - append("INNER JOIN event_tags as event_tagsAll${index}_$valueIndex ON event_tagsAll${index}_$valueIndex.event_header_row_id = event_tags.event_header_row_id ") + append("INNER JOIN event_tags as event_tagsAll${index}_$valueIndex ON event_tagsAll${index}_$valueIndex.event_header_row_id = event_tags.event_header_row_id AND event_tagsAll${index}_$valueIndex.created_at = event_tags.created_at ") } else { defaultTagKey = TagNameForQuery.AllTags(tagName, valueIndex) } } } - if (hasHeaders) { + if (needHeaders) { append("INNER JOIN event_headers ON event_headers.row_id = event_tags.event_header_row_id ") } @@ -525,10 +540,6 @@ class EventIndexesModule( // ids reduce the filter the most filter.ids?.let { equalsOrIn("event_headers.id", it) } - // range search is bad but most of the time these are up the top with few elements. - filter.since?.let { greaterThanOrEquals("event_headers.created_at", it) } - filter.until?.let { lessThanOrEquals("event_headers.created_at", it) } - // it's quite rare to have 2 tags in the filter, but possible nonDTagsIn.keys.forEachIndexed { index, tagName -> val column = @@ -560,6 +571,15 @@ class EventIndexesModule( } } + // range search is bad but most of the time these are up the top with few elements. + if (reverseLookup) { + filter.since?.let { greaterThanOrEquals("event_tags.created_at", it) } + filter.until?.let { lessThanOrEquals("event_tags.created_at", it) } + } else { + filter.since?.let { greaterThanOrEquals("event_headers.created_at", it) } + filter.until?.let { lessThanOrEquals("event_headers.created_at", it) } + } + filter.kinds?.let { equalsOrIn("event_headers.kind", it) } filter.authors?.let { equalsOrIn("event_headers.pubkey", it) } @@ -580,7 +600,11 @@ class EventIndexesModule( val whereClause = if (filter.limit != null) { - "${clause.conditions} ORDER BY event_headers.created_at DESC, event_headers.id ASC LIMIT ${filter.limit}" + if (reverseLookup) { + "${clause.conditions} ORDER BY event_tags.created_at DESC LIMIT ${filter.limit}" + } else { + "${clause.conditions} ORDER BY event_headers.created_at DESC, event_headers.id ASC LIMIT ${filter.limit}" + } } else { clause.conditions } From 4f1ad11d79796ad5e28e1e2ad58092b6ae29bb0e Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Wed, 31 Dec 2025 09:15:20 -0500 Subject: [PATCH 07/63] Moves SQLBuilder to its own class --- .../store/sqlite/QueryAssemblerTest.kt | 2 +- .../store/sqlite/EventIndexesModule.kt | 435 ---------------- .../nip01Core/store/sqlite/QueryBuilder.kt | 467 ++++++++++++++++++ .../store/sqlite/SQLiteEventStore.kt | 18 +- 4 files changed, 478 insertions(+), 444 deletions(-) create mode 100644 quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryBuilder.kt diff --git a/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryAssemblerTest.kt b/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryAssemblerTest.kt index 9a6000835..67162ad12 100644 --- a/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryAssemblerTest.kt +++ b/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryAssemblerTest.kt @@ -32,7 +32,7 @@ import org.junit.Test class QueryAssemblerTest { val hasher = TagNameValueHasher(0) - val builder = EventIndexesModule(FullTextSearchModule(), { hasher }) + val builder = QueryBuilder(FullTextSearchModule(), { hasher }) val key1 = "7c5eb72a4584fdaaeaa145b25c92ea9917704224951219dbd43acef9e91fb88d" val key2 = "f3ac434d61bc0f491a814782ccfdf9c439dae1f0bde9097ad4a245f4c495cd14" diff --git a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/EventIndexesModule.kt b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/EventIndexesModule.kt index 981260c58..e8410d5a5 100644 --- a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/EventIndexesModule.kt +++ b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/EventIndexesModule.kt @@ -20,18 +20,12 @@ */ package com.vitorpamplona.quartz.nip01Core.store.sqlite -import android.database.Cursor import android.database.sqlite.SQLiteDatabase import com.vitorpamplona.quartz.nip01Core.core.AddressSerializer import com.vitorpamplona.quartz.nip01Core.core.AddressableEvent import com.vitorpamplona.quartz.nip01Core.core.Event -import com.vitorpamplona.quartz.nip01Core.core.HexKey -import com.vitorpamplona.quartz.nip01Core.core.Kind import com.vitorpamplona.quartz.nip01Core.core.OptimizedJsonMapper -import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter -import com.vitorpamplona.quartz.nip01Core.store.sqlite.sql.where import com.vitorpamplona.quartz.nip59Giftwrap.wraps.GiftWrapEvent -import com.vitorpamplona.quartz.utils.EventFactory class EventIndexesModule( val fts: FullTextSearchModule, @@ -188,437 +182,8 @@ class EventIndexesModule( return headerId } - fun planQuery( - filter: Filter, - hasher: TagNameValueHasher, - db: SQLiteDatabase, - ): String { - val rowIdSubQuery = prepareRowIDSubQueries(filter, hasher) - - return if (rowIdSubQuery == null) { - val query = makeEverythingQuery() - db.explainQuery(query) - } else { - val query = makeQueryIn(rowIdSubQuery.sql) - db.explainQuery(query, rowIdSubQuery.args.toTypedArray()) - } - } - - fun query( - filter: Filter, - db: SQLiteDatabase, - ): List { - val rowIdSubQuery = prepareRowIDSubQueries(filter, hasher(db)) - - return if (rowIdSubQuery == null) { - db.runQuery(makeEverythingQuery()) - } else { - db.runQuery(makeQueryIn(rowIdSubQuery.sql), rowIdSubQuery.args) - } - } - - fun query( - filter: Filter, - db: SQLiteDatabase, - onEach: (T) -> Unit, - ) { - val rowIdSubQuery = prepareRowIDSubQueries(filter, hasher(db)) - - return if (rowIdSubQuery == null) { - db.runQuery(makeEverythingQuery(), onEach = onEach) - } else { - db.runQuery(makeQueryIn(rowIdSubQuery.sql), rowIdSubQuery.args, onEach) - } - } - - fun planQuery( - filters: List, - hasher: TagNameValueHasher, - db: SQLiteDatabase, - ): String { - val rowIdSubQuery = unionSubqueriesIfNeeded(filters, hasher) - - return if (rowIdSubQuery == null) { - val query = makeEverythingQuery() - db.explainQuery(query) - } else { - val query = makeQueryIn(rowIdSubQuery.sql) - db.explainQuery(query, rowIdSubQuery.args.toTypedArray()) - } - } - - fun query( - filters: List, - db: SQLiteDatabase, - ): List { - val rowIdSubqueries = unionSubqueriesIfNeeded(filters, hasher(db)) ?: return db.runQuery(makeEverythingQuery()) - return db.runQuery(makeQueryIn(rowIdSubqueries.sql), rowIdSubqueries.args) - } - - fun query( - filters: List, - db: SQLiteDatabase, - onEach: (T) -> Unit, - ) { - val rowIdSubqueries = unionSubqueriesIfNeeded(filters, hasher(db)) - - if (rowIdSubqueries == null) { - db.runQuery(makeEverythingQuery(), onEach = onEach) - } else { - db.runQuery(makeQueryIn(rowIdSubqueries.sql), rowIdSubqueries.args, onEach) - } - } - - private fun makeEverythingQuery() = "SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers ORDER BY created_at DESC, id" - - private fun makeQueryIn(rowIdQuery: String) = - """ - SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers - INNER JOIN ( - $rowIdQuery - ) AS filtered - ON event_headers.row_id = filtered.row_id - ORDER BY created_at DESC, id - """.trimIndent() - - private fun SQLiteDatabase.runQuery( - sql: String, - args: List = emptyList(), - ): List = - rawQuery(sql, args.toTypedArray()).use { cursor -> - ArrayList(cursor.count).apply { - while (cursor.moveToNext()) { - add(cursor.toEvent()) - } - } - } - - private inline fun SQLiteDatabase.runQuery( - sql: String, - args: List = emptyList(), - onEach: (T) -> Unit, - ) = rawQuery(sql, args.toTypedArray()).use { cursor -> - while (cursor.moveToNext()) { - onEach(cursor.toEvent()) - } - } - - private fun Cursor.toEvent() = - EventFactory.create( - getString(0).intern(), - getString(1).intern(), - getLong(2), - getInt(3), - OptimizedJsonMapper.fromJsonToTagArray(getString(4)), - getString(5), - getString(6), - ) - - class RawEvent( - val id: HexKey, - val pubKey: HexKey, - val createdAt: Long, - val kind: Kind, - val jsonTags: String, - val content: String, - val sig: HexKey, - ) { - fun toEvent() = - EventFactory.create( - id.intern(), - pubKey.intern(), - createdAt, - kind, - OptimizedJsonMapper.fromJsonToTagArray(jsonTags), - content, - sig, - ) - } - - private fun Cursor.toRawEvent() = - RawEvent( - getString(0), - getString(1), - getLong(2), - getInt(3), - getString(4), - getString(5), - getString(6), - ) - - // -------------- - // Counts - // ------------- - fun count( - filter: Filter, - db: SQLiteDatabase, - ): Int { - val rowIdSubQuery = prepareRowIDSubQueries(filter, hasher(db)) - - return if (rowIdSubQuery == null) { - db.countEverything() - } else { - db.countIn(rowIdSubQuery.sql, rowIdSubQuery.args) - } - } - - fun count( - filters: List, - db: SQLiteDatabase, - ): Int { - val rowIdSubqueries = unionSubqueriesIfNeeded(filters, hasher(db)) ?: return db.countEverything() - - return db.countIn(rowIdSubqueries.sql, rowIdSubqueries.args) - } - - private fun SQLiteDatabase.countEverything() = runCount("SELECT count(*) as count FROM event_headers") - - private fun SQLiteDatabase.countIn( - rowIdQuery: String, - args: List, - ) = runCount("SELECT COUNT(*) as count FROM ($rowIdQuery)", args) - - private fun SQLiteDatabase.runCount( - sql: String, - args: List = emptyList(), - ): Int = - rawQuery(sql, args.toTypedArray()).use { cursor -> - cursor.moveToNext() - cursor.getInt(0) - } - - // -------------- - // Deletes - // ------------- - fun delete( - filter: Filter, - db: SQLiteDatabase, - ): Int { - val rowIdQuery = prepareRowIDSubQueries(filter, hasher(db)) - - return if (rowIdQuery == null) { - 0 - } else { - db.runDelete(rowIdQuery.sql, rowIdQuery.args) - } - } - - fun delete( - filters: List, - db: SQLiteDatabase, - ): Int { - val rowIdSubqueries = unionSubqueriesIfNeeded(filters, hasher(db)) ?: return 0 - - return db.runDelete(rowIdSubqueries.sql, rowIdSubqueries.args) - } - - private fun SQLiteDatabase.runDelete( - sql: String, - args: List = emptyList(), - ): Int = delete("event_headers", "row_id IN ($sql)", args.toTypedArray()) - - // --------------------------------- - // Prepare unions of all the filters - // --------------------------------- - fun unionSubqueriesIfNeeded( - filters: List, - hasher: TagNameValueHasher, - ): RowIdSubQuery? { - val inner = - filters.mapNotNull { filter -> - prepareRowIDSubQueries(filter, hasher) - } - - if (inner.isEmpty()) return null - - return if (inner.size == 1) { - inner.first() - } else { - RowIdSubQuery( - sql = inner.joinToString("\n UNION\n ") { "SELECT row_id FROM (${it.sql})" }, - args = inner.flatMap { it.args }, - ) - } - } - - sealed class TagNameForQuery { - class InTags( - val tagName: String, - ) : TagNameForQuery() - - class AllTags( - val tagName: String, - val tagValueIndex: Int, - ) : TagNameForQuery() - } - - // ---------------------------- - // Inner row id selections - // ---------------------------- - fun prepareRowIDSubQueries( - filter: Filter, - hasher: TagNameValueHasher, - ): RowIdSubQuery? { - if (!filter.isFilledFilter()) return null - - val mustJoinSearch = (filter.search != null) - - val nonDTagsIn = filter.tags?.filter { it.key != "d" } ?: emptyMap() - - val nonDTagsAll = filter.tagsAll?.filter { it.key != "d" } ?: emptyMap() - - val reverseLookup = nonDTagsIn.isNotEmpty() || nonDTagsAll.isNotEmpty() - - val needHeaders = - with(filter) { - (ids != null) || - (authors != null && authors.isNotEmpty()) || - (kinds != null && kinds.isNotEmpty()) || - (tags != null && tags.containsKey("d")) - } - - val hasHeaders = - with(filter) { - (ids != null) || - (authors != null && authors.isNotEmpty()) || - (kinds != null && kinds.isNotEmpty()) || - (tags != null && tags.containsKey("d")) || - (since != null) || - (until != null) || - (limit != null) - } - - var defaultTagKey: TagNameForQuery? = null - - val projection = - buildString { - // always do tags if there are any - if (reverseLookup) { - append("SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags ") - - // it's quite rare to have 2 tags in the filter, but possible - nonDTagsIn.keys.forEachIndexed { index, tagName -> - if (defaultTagKey != null) { - append("INNER JOIN event_tags as event_tagsIn$index ON event_tagsIn$index.event_header_row_id = event_tags.event_header_row_id AND event_tagsIn$index.created_at = event_tags.created_at ") - } else { - defaultTagKey = TagNameForQuery.InTags(tagName) - } - } - - nonDTagsAll.keys.forEachIndexed { index, tagName -> - nonDTagsAll[tagName]!!.forEachIndexed { valueIndex, tagValue -> - if (defaultTagKey != null) { - append("INNER JOIN event_tags as event_tagsAll${index}_$valueIndex ON event_tagsAll${index}_$valueIndex.event_header_row_id = event_tags.event_header_row_id AND event_tagsAll${index}_$valueIndex.created_at = event_tags.created_at ") - } else { - defaultTagKey = TagNameForQuery.AllTags(tagName, valueIndex) - } - } - } - - if (needHeaders) { - append("INNER JOIN event_headers ON event_headers.row_id = event_tags.event_header_row_id ") - } - - if (mustJoinSearch) { - append("INNER JOIN ${fts.tableName} ON ${fts.tableName}.${fts.eventHeaderRowIdName} = event_tags.event_header_row_id ") - } - } else if (mustJoinSearch) { - append("SELECT ${fts.tableName}.${fts.eventHeaderRowIdName} as row_id FROM ${fts.tableName} ") - - if (hasHeaders) { - append("INNER JOIN event_headers ON event_headers.row_id = ${fts.tableName}.${fts.eventHeaderRowIdName}") - } - } else { - // no tags and no search. - append("SELECT event_headers.row_id as row_id FROM event_headers ") - } - } - - val clause = - where { - // the order should match indexes - // ids reduce the filter the most - filter.ids?.let { equalsOrIn("event_headers.id", it) } - - // it's quite rare to have 2 tags in the filter, but possible - nonDTagsIn.keys.forEachIndexed { index, tagName -> - val column = - if (defaultTagKey == null || (defaultTagKey is TagNameForQuery.InTags && defaultTagKey.tagName == tagName)) { - "event_tags.tag_hash" - } else { - "event_tagsIn$index.tag_hash" - } - - equalsOrIn( - column, - nonDTagsIn[tagName]!!.map { - hasher.hash(tagName, it) - }, - ) - } - - // there are indexes for these, starting with tags. - nonDTagsAll.keys.forEachIndexed { index, tagName -> - nonDTagsAll[tagName]!!.forEachIndexed { valueIndex, tagValue -> - val column = - if (defaultTagKey == null || (defaultTagKey is TagNameForQuery.AllTags && defaultTagKey.tagName == tagName && defaultTagKey.tagValueIndex == valueIndex)) { - "event_tags.tag_hash" - } else { - "event_tagsAll${index}_$valueIndex.tag_hash" - } - - equals(column, hasher.hash(tagName, tagValue)) - } - } - - // range search is bad but most of the time these are up the top with few elements. - if (reverseLookup) { - filter.since?.let { greaterThanOrEquals("event_tags.created_at", it) } - filter.until?.let { lessThanOrEquals("event_tags.created_at", it) } - } else { - filter.since?.let { greaterThanOrEquals("event_headers.created_at", it) } - filter.until?.let { lessThanOrEquals("event_headers.created_at", it) } - } - - filter.kinds?.let { equalsOrIn("event_headers.kind", it) } - filter.authors?.let { equalsOrIn("event_headers.pubkey", it) } - - // there are indexes for these, starting with tags. - filter.tags?.forEach { (tagName, tagValues) -> - if (tagName == "d") { - equalsOrIn("event_headers.d_tag", tagValues) - } - } - - // if search is included, SQLLite will always start here. - filter.search?.let { - if (it.isNotBlank()) { - match(fts.tableName, it) - } - } - } - - val whereClause = - if (filter.limit != null) { - if (reverseLookup) { - "${clause.conditions} ORDER BY event_tags.created_at DESC LIMIT ${filter.limit}" - } else { - "${clause.conditions} ORDER BY event_headers.created_at DESC, event_headers.id ASC LIMIT ${filter.limit}" - } - } else { - clause.conditions - } - - return RowIdSubQuery("$projection WHERE $whereClause", clause.args) - } - override fun deleteAll(db: SQLiteDatabase) { db.execSQL("DELETE FROM event_tags") db.execSQL("DELETE FROM event_headers") } - - data class RowIdSubQuery( - val sql: String, - val args: List, - ) } diff --git a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryBuilder.kt b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryBuilder.kt new file mode 100644 index 000000000..0d3a5bb79 --- /dev/null +++ b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryBuilder.kt @@ -0,0 +1,467 @@ +/** + * Copyright (c) 2025 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip01Core.store.sqlite + +import android.database.Cursor +import android.database.sqlite.SQLiteDatabase +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.core.HexKey +import com.vitorpamplona.quartz.nip01Core.core.Kind +import com.vitorpamplona.quartz.nip01Core.core.OptimizedJsonMapper +import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter +import com.vitorpamplona.quartz.nip01Core.store.sqlite.sql.where +import com.vitorpamplona.quartz.utils.EventFactory +import kotlin.collections.component1 +import kotlin.collections.component2 + +class QueryBuilder( + val fts: FullTextSearchModule, + val hasher: (db: SQLiteDatabase) -> TagNameValueHasher, +) { + fun planQuery( + filter: Filter, + hasher: TagNameValueHasher, + db: SQLiteDatabase, + ): String { + val rowIdSubQuery = prepareRowIDSubQueries(filter, hasher) + + return if (rowIdSubQuery == null) { + val query = makeEverythingQuery() + db.explainQuery(query) + } else { + val query = makeQueryIn(rowIdSubQuery.sql) + db.explainQuery(query, rowIdSubQuery.args.toTypedArray()) + } + } + + fun query( + filter: Filter, + db: SQLiteDatabase, + ): List { + val rowIdSubQuery = prepareRowIDSubQueries(filter, hasher(db)) + + return if (rowIdSubQuery == null) { + db.runQuery(makeEverythingQuery()) + } else { + db.runQuery(makeQueryIn(rowIdSubQuery.sql), rowIdSubQuery.args) + } + } + + fun query( + filter: Filter, + db: SQLiteDatabase, + onEach: (T) -> Unit, + ) { + val rowIdSubQuery = prepareRowIDSubQueries(filter, hasher(db)) + + return if (rowIdSubQuery == null) { + db.runQuery(makeEverythingQuery(), onEach = onEach) + } else { + db.runQuery(makeQueryIn(rowIdSubQuery.sql), rowIdSubQuery.args, onEach) + } + } + + fun planQuery( + filters: List, + hasher: TagNameValueHasher, + db: SQLiteDatabase, + ): String { + val rowIdSubQuery = unionSubqueriesIfNeeded(filters, hasher) + + return if (rowIdSubQuery == null) { + val query = makeEverythingQuery() + db.explainQuery(query) + } else { + val query = makeQueryIn(rowIdSubQuery.sql) + db.explainQuery(query, rowIdSubQuery.args.toTypedArray()) + } + } + + fun query( + filters: List, + db: SQLiteDatabase, + ): List { + val rowIdSubqueries = unionSubqueriesIfNeeded(filters, hasher(db)) ?: return db.runQuery(makeEverythingQuery()) + return db.runQuery(makeQueryIn(rowIdSubqueries.sql), rowIdSubqueries.args) + } + + fun query( + filters: List, + db: SQLiteDatabase, + onEach: (T) -> Unit, + ) { + val rowIdSubqueries = unionSubqueriesIfNeeded(filters, hasher(db)) + + if (rowIdSubqueries == null) { + db.runQuery(makeEverythingQuery(), onEach = onEach) + } else { + db.runQuery(makeQueryIn(rowIdSubqueries.sql), rowIdSubqueries.args, onEach) + } + } + + private fun makeEverythingQuery() = "SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers ORDER BY created_at DESC, id" + + private fun makeQueryIn(rowIdQuery: String) = + """ + SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers + INNER JOIN ( + $rowIdQuery + ) AS filtered + ON event_headers.row_id = filtered.row_id + ORDER BY created_at DESC, id + """.trimIndent() + + private fun SQLiteDatabase.runQuery( + sql: String, + args: List = emptyList(), + ): List = + rawQuery(sql, args.toTypedArray()).use { cursor -> + ArrayList(cursor.count).apply { + while (cursor.moveToNext()) { + add(cursor.toEvent()) + } + } + } + + private inline fun SQLiteDatabase.runQuery( + sql: String, + args: List = emptyList(), + onEach: (T) -> Unit, + ) = rawQuery(sql, args.toTypedArray()).use { cursor -> + while (cursor.moveToNext()) { + onEach(cursor.toEvent()) + } + } + + private fun Cursor.toEvent() = + EventFactory.create( + getString(0).intern(), + getString(1).intern(), + getLong(2), + getInt(3), + OptimizedJsonMapper.fromJsonToTagArray(getString(4)), + getString(5), + getString(6), + ) + + class RawEvent( + val id: HexKey, + val pubKey: HexKey, + val createdAt: Long, + val kind: Kind, + val jsonTags: String, + val content: String, + val sig: HexKey, + ) { + fun toEvent() = + EventFactory.create( + id.intern(), + pubKey.intern(), + createdAt, + kind, + OptimizedJsonMapper.fromJsonToTagArray(jsonTags), + content, + sig, + ) + } + + private fun Cursor.toRawEvent() = + RawEvent( + getString(0), + getString(1), + getLong(2), + getInt(3), + getString(4), + getString(5), + getString(6), + ) + + // -------------- + // Counts + // ------------- + fun count( + filter: Filter, + db: SQLiteDatabase, + ): Int { + val rowIdSubQuery = prepareRowIDSubQueries(filter, hasher(db)) + + return if (rowIdSubQuery == null) { + db.countEverything() + } else { + db.countIn(rowIdSubQuery.sql, rowIdSubQuery.args) + } + } + + fun count( + filters: List, + db: SQLiteDatabase, + ): Int { + val rowIdSubqueries = unionSubqueriesIfNeeded(filters, hasher(db)) ?: return db.countEverything() + + return db.countIn(rowIdSubqueries.sql, rowIdSubqueries.args) + } + + private fun SQLiteDatabase.countEverything() = runCount("SELECT count(*) as count FROM event_headers") + + private fun SQLiteDatabase.countIn( + rowIdQuery: String, + args: List, + ) = runCount("SELECT COUNT(*) as count FROM ($rowIdQuery)", args) + + private fun SQLiteDatabase.runCount( + sql: String, + args: List = emptyList(), + ): Int = + rawQuery(sql, args.toTypedArray()).use { cursor -> + cursor.moveToNext() + cursor.getInt(0) + } + + // -------------- + // Deletes + // ------------- + fun delete( + filter: Filter, + db: SQLiteDatabase, + ): Int { + val rowIdQuery = prepareRowIDSubQueries(filter, hasher(db)) + + return if (rowIdQuery == null) { + 0 + } else { + db.runDelete(rowIdQuery.sql, rowIdQuery.args) + } + } + + fun delete( + filters: List, + db: SQLiteDatabase, + ): Int { + val rowIdSubqueries = unionSubqueriesIfNeeded(filters, hasher(db)) ?: return 0 + + return db.runDelete(rowIdSubqueries.sql, rowIdSubqueries.args) + } + + private fun SQLiteDatabase.runDelete( + sql: String, + args: List = emptyList(), + ): Int = delete("event_headers", "row_id IN ($sql)", args.toTypedArray()) + + // --------------------------------- + // Prepare unions of all the filters + // --------------------------------- + fun unionSubqueriesIfNeeded( + filters: List, + hasher: TagNameValueHasher, + ): RowIdSubQuery? { + val inner = + filters.mapNotNull { filter -> + prepareRowIDSubQueries(filter, hasher) + } + + if (inner.isEmpty()) return null + + return if (inner.size == 1) { + inner.first() + } else { + RowIdSubQuery( + sql = inner.joinToString("\n UNION\n ") { "SELECT row_id FROM (${it.sql})" }, + args = inner.flatMap { it.args }, + ) + } + } + + sealed class TagNameForQuery { + class InTags( + val tagName: String, + ) : TagNameForQuery() + + class AllTags( + val tagName: String, + val tagValueIndex: Int, + ) : TagNameForQuery() + } + + // ---------------------------- + // Inner row id selections + // ---------------------------- + fun prepareRowIDSubQueries( + filter: Filter, + hasher: TagNameValueHasher, + ): RowIdSubQuery? { + if (!filter.isFilledFilter()) return null + + val mustJoinSearch = (filter.search != null) + + val nonDTagsIn = filter.tags?.filter { it.key != "d" } ?: emptyMap() + + val nonDTagsAll = filter.tagsAll?.filter { it.key != "d" } ?: emptyMap() + + val reverseLookup = nonDTagsIn.isNotEmpty() || nonDTagsAll.isNotEmpty() + + val needHeaders = + with(filter) { + (ids != null) || + (authors != null && authors.isNotEmpty()) || + (kinds != null && kinds.isNotEmpty()) || + (tags != null && tags.containsKey("d")) + } + + val hasHeaders = + with(filter) { + (ids != null) || + (authors != null && authors.isNotEmpty()) || + (kinds != null && kinds.isNotEmpty()) || + (tags != null && tags.containsKey("d")) || + (since != null) || + (until != null) || + (limit != null) + } + + var defaultTagKey: TagNameForQuery? = null + + val projection = + buildString { + // always do tags if there are any + if (reverseLookup) { + append("SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags ") + + // it's quite rare to have 2 tags in the filter, but possible + nonDTagsIn.keys.forEachIndexed { index, tagName -> + if (defaultTagKey != null) { + append("INNER JOIN event_tags as event_tagsIn$index ON event_tagsIn$index.event_header_row_id = event_tags.event_header_row_id AND event_tagsIn$index.created_at = event_tags.created_at ") + } else { + defaultTagKey = TagNameForQuery.InTags(tagName) + } + } + + nonDTagsAll.keys.forEachIndexed { index, tagName -> + nonDTagsAll[tagName]!!.forEachIndexed { valueIndex, tagValue -> + if (defaultTagKey != null) { + append("INNER JOIN event_tags as event_tagsAll${index}_$valueIndex ON event_tagsAll${index}_$valueIndex.event_header_row_id = event_tags.event_header_row_id AND event_tagsAll${index}_$valueIndex.created_at = event_tags.created_at ") + } else { + defaultTagKey = TagNameForQuery.AllTags(tagName, valueIndex) + } + } + } + + if (needHeaders) { + append("INNER JOIN event_headers ON event_headers.row_id = event_tags.event_header_row_id ") + } + + if (mustJoinSearch) { + append("INNER JOIN ${fts.tableName} ON ${fts.tableName}.${fts.eventHeaderRowIdName} = event_tags.event_header_row_id ") + } + } else if (mustJoinSearch) { + append("SELECT ${fts.tableName}.${fts.eventHeaderRowIdName} as row_id FROM ${fts.tableName} ") + + if (hasHeaders) { + append("INNER JOIN event_headers ON event_headers.row_id = ${fts.tableName}.${fts.eventHeaderRowIdName}") + } + } else { + // no tags and no search. + append("SELECT event_headers.row_id as row_id FROM event_headers ") + } + } + + val clause = + where { + // the order should match indexes + // ids reduce the filter the most + filter.ids?.let { equalsOrIn("event_headers.id", it) } + + // it's quite rare to have 2 tags in the filter, but possible + nonDTagsIn.keys.forEachIndexed { index, tagName -> + val column = + if (defaultTagKey == null || (defaultTagKey is TagNameForQuery.InTags && defaultTagKey.tagName == tagName)) { + "event_tags.tag_hash" + } else { + "event_tagsIn$index.tag_hash" + } + + equalsOrIn( + column, + nonDTagsIn[tagName]!!.map { + hasher.hash(tagName, it) + }, + ) + } + + // there are indexes for these, starting with tags. + nonDTagsAll.keys.forEachIndexed { index, tagName -> + nonDTagsAll[tagName]!!.forEachIndexed { valueIndex, tagValue -> + val column = + if (defaultTagKey == null || (defaultTagKey is TagNameForQuery.AllTags && defaultTagKey.tagName == tagName && defaultTagKey.tagValueIndex == valueIndex)) { + "event_tags.tag_hash" + } else { + "event_tagsAll${index}_$valueIndex.tag_hash" + } + + equals(column, hasher.hash(tagName, tagValue)) + } + } + + // range search is bad but most of the time these are up the top with few elements. + if (reverseLookup) { + filter.since?.let { greaterThanOrEquals("event_tags.created_at", it) } + filter.until?.let { lessThanOrEquals("event_tags.created_at", it) } + } else { + filter.since?.let { greaterThanOrEquals("event_headers.created_at", it) } + filter.until?.let { lessThanOrEquals("event_headers.created_at", it) } + } + + filter.kinds?.let { equalsOrIn("event_headers.kind", it) } + filter.authors?.let { equalsOrIn("event_headers.pubkey", it) } + + // there are indexes for these, starting with tags. + filter.tags?.forEach { (tagName, tagValues) -> + if (tagName == "d") { + equalsOrIn("event_headers.d_tag", tagValues) + } + } + + // if search is included, SQLLite will always start here. + filter.search?.let { + if (it.isNotBlank()) { + match(fts.tableName, it) + } + } + } + + val whereClause = + if (filter.limit != null) { + if (reverseLookup) { + "${clause.conditions} ORDER BY event_tags.created_at DESC LIMIT ${filter.limit}" + } else { + "${clause.conditions} ORDER BY event_headers.created_at DESC, event_headers.id ASC LIMIT ${filter.limit}" + } + } else { + clause.conditions + } + + return RowIdSubQuery("$projection WHERE $whereClause", clause.args) + } + + data class RowIdSubQuery( + val sql: String, + val args: List, + ) +} diff --git a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/SQLiteEventStore.kt b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/SQLiteEventStore.kt index c1e72a3bb..c51d50753 100644 --- a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/SQLiteEventStore.kt +++ b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/SQLiteEventStore.kt @@ -57,6 +57,8 @@ class SQLiteEventStore( val expirationModule = ExpirationModule() val rightToVanishModule = RightToVanishModule(seedModule::hasher) + val queryBuilder = QueryBuilder(fullTextSearchModule, seedModule::hasher) + val modules = listOf( seedModule, @@ -171,30 +173,30 @@ class SQLiteEventStore( } } - fun query(filter: Filter): List = eventIndexModule.query(filter, readableDatabase) + fun query(filter: Filter): List = queryBuilder.query(filter, readableDatabase) - fun query(filters: List): List = eventIndexModule.query(filters, readableDatabase) + fun query(filters: List): List = queryBuilder.query(filters, readableDatabase) fun query( filter: Filter, onEach: (T) -> Unit, - ) = eventIndexModule.query(filter, readableDatabase, onEach) + ) = queryBuilder.query(filter, readableDatabase, onEach) fun query( filters: List, onEach: (T) -> Unit, - ) = eventIndexModule.query(filters, readableDatabase, onEach) + ) = queryBuilder.query(filters, readableDatabase, onEach) - fun count(filter: Filter): Int = eventIndexModule.count(filter, readableDatabase) + fun count(filter: Filter): Int = queryBuilder.count(filter, readableDatabase) - fun count(filters: List): Int = eventIndexModule.count(filters, readableDatabase) + fun count(filters: List): Int = queryBuilder.count(filters, readableDatabase) fun delete(filter: Filter) { - eventIndexModule.delete(filter, writableDatabase) + queryBuilder.delete(filter, writableDatabase) } fun delete(filters: List) { - eventIndexModule.delete(filters, writableDatabase) + queryBuilder.delete(filters, writableDatabase) } fun delete(id: HexKey): Int = writableDatabase.delete("event_headers", "id = ?", arrayOf(id)) From 780ea487aa12b746cb825edac985492d411f987a Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Wed, 31 Dec 2025 09:42:54 -0500 Subject: [PATCH 08/63] Adds a test case to simulate reports --- .../store/sqlite/QueryAssemblerTest.kt | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryAssemblerTest.kt b/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryAssemblerTest.kt index 67162ad12..58f97af0c 100644 --- a/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryAssemblerTest.kt +++ b/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryAssemblerTest.kt @@ -532,4 +532,41 @@ class QueryAssemblerTest { sql, ) } + + @Test + fun testReportLikeFilter() { + val sql = + explain( + Filter( + kinds = listOf(ContactListEvent.KIND), + authors = listOf("460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c"), + tags = + mapOf( + "p" to listOf("460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c"), + ), + limit = 500, + ), + ) + + println(sql) + + TestCase.assertEquals( + """ + SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers + INNER JOIN ( + SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags INNER JOIN event_headers ON event_headers.row_id = event_tags.event_header_row_id WHERE (event_tags.tag_hash = "-4551135004136952885") AND (event_headers.kind = "3") AND (event_headers.pubkey = "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c") ORDER BY event_tags.created_at DESC LIMIT 500 + ) AS filtered + ON event_headers.row_id = filtered.row_id + ORDER BY created_at DESC, id + ├── CO-ROUTINE filtered + │ ├── SEARCH event_tags USING INDEX query_by_tags_hash (tag_hash=?) + │ ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) + │ └── USE TEMP B-TREE FOR DISTINCT + ├── SCAN filtered + ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) + └── USE TEMP B-TREE FOR ORDER BY + """.trimIndent(), + sql, + ) + } } From 4f7972df90e3db06176cbbe7061f8f77dd9e1395 Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Wed, 31 Dec 2025 13:37:02 -0500 Subject: [PATCH 09/63] Removes logs --- .../nip01Core/store/sqlite/QueryAssemblerTest.kt | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryAssemblerTest.kt b/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryAssemblerTest.kt index 58f97af0c..46c836c0d 100644 --- a/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryAssemblerTest.kt +++ b/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryAssemblerTest.kt @@ -25,6 +25,7 @@ import androidx.test.core.app.ApplicationProvider import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter import com.vitorpamplona.quartz.nip02FollowList.ContactListEvent import junit.framework.TestCase +import junit.framework.TestCase.assertEquals import org.junit.After import org.junit.Assert import org.junit.Before @@ -337,9 +338,6 @@ class QueryAssemblerTest { ), ), ) - - println(sql) - TestCase.assertEquals( """ SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers @@ -512,7 +510,6 @@ class QueryAssemblerTest { @Test fun testAllTag() { val sql = explain(Filter(tagsAll = mapOf("p" to listOf(key1, key2)))) - println(sql) TestCase.assertEquals( """ SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers @@ -547,10 +544,7 @@ class QueryAssemblerTest { limit = 500, ), ) - - println(sql) - - TestCase.assertEquals( + assertEquals( """ SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers INNER JOIN ( From 6713c3bd507bf884cb491ff38452bffea11b3bab Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Wed, 31 Dec 2025 13:39:17 -0500 Subject: [PATCH 10/63] Adds performance and flexibility by exposing Raw methods --- .../nip01Core/store/sqlite/QueryBuilder.kt | 199 ++++++++++-------- .../store/sqlite/SQLiteEventStore.kt | 38 ++++ 2 files changed, 147 insertions(+), 90 deletions(-) diff --git a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryBuilder.kt b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryBuilder.kt index 0d3a5bb79..94713826c 100644 --- a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryBuilder.kt +++ b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryBuilder.kt @@ -23,8 +23,6 @@ package com.vitorpamplona.quartz.nip01Core.store.sqlite import android.database.Cursor import android.database.sqlite.SQLiteDatabase import com.vitorpamplona.quartz.nip01Core.core.Event -import com.vitorpamplona.quartz.nip01Core.core.HexKey -import com.vitorpamplona.quartz.nip01Core.core.Kind import com.vitorpamplona.quartz.nip01Core.core.OptimizedJsonMapper import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter import com.vitorpamplona.quartz.nip01Core.store.sqlite.sql.where @@ -36,47 +34,66 @@ class QueryBuilder( val fts: FullTextSearchModule, val hasher: (db: SQLiteDatabase) -> TagNameValueHasher, ) { - fun planQuery( - filter: Filter, - hasher: TagNameValueHasher, - db: SQLiteDatabase, - ): String { - val rowIdSubQuery = prepareRowIDSubQueries(filter, hasher) - - return if (rowIdSubQuery == null) { - val query = makeEverythingQuery() - db.explainQuery(query) - } else { - val query = makeQueryIn(rowIdSubQuery.sql) - db.explainQuery(query, rowIdSubQuery.args.toTypedArray()) - } - } - + // ------------ + // Main methods + // ------------ fun query( filter: Filter, db: SQLiteDatabase, - ): List { - val rowIdSubQuery = prepareRowIDSubQueries(filter, hasher(db)) - - return if (rowIdSubQuery == null) { - db.runQuery(makeEverythingQuery()) - } else { - db.runQuery(makeQueryIn(rowIdSubQuery.sql), rowIdSubQuery.args) - } - } + ): List = db.runQuery(toSql(filter, hasher(db))) fun query( filter: Filter, db: SQLiteDatabase, onEach: (T) -> Unit, - ) { - val rowIdSubQuery = prepareRowIDSubQueries(filter, hasher(db)) + ) = db.runQuery(toSql(filter, hasher(db)), onEach) - return if (rowIdSubQuery == null) { - db.runQuery(makeEverythingQuery(), onEach = onEach) - } else { - db.runQuery(makeQueryIn(rowIdSubQuery.sql), rowIdSubQuery.args, onEach) - } + fun query( + filters: List, + db: SQLiteDatabase, + ): List = db.runQuery(toSql(filters, hasher(db))) + + fun query( + filters: List, + db: SQLiteDatabase, + onEach: (T) -> Unit, + ) = db.runQuery(toSql(filters, hasher(db)), onEach) + + // --------------------------- + // Raw methods for performance + // --------------------------- + fun rawQuery( + filter: Filter, + db: SQLiteDatabase, + ): List = db.runRawQuery(toSql(filter, hasher(db))) + + fun rawQuery( + filter: Filter, + db: SQLiteDatabase, + onEach: (RawEvent) -> Unit, + ) = db.runRawQuery(toSql(filter, hasher(db)), onEach) + + fun rawQuery( + filters: List, + db: SQLiteDatabase, + ): List = db.runRawQuery(toSql(filters, hasher(db))) + + fun rawQuery( + filters: List, + db: SQLiteDatabase, + onEach: (RawEvent) -> Unit, + ) = db.runRawQuery(toSql(filters, hasher(db)), onEach) + + // ----------- + // Debug Tools + // ----------- + fun planQuery( + filter: Filter, + hasher: TagNameValueHasher, + db: SQLiteDatabase, + ): String { + val query = toSql(filter, hasher) + return db.explainQuery(query.sql, query.args.toTypedArray()) } fun planQuery( @@ -84,36 +101,45 @@ class QueryBuilder( hasher: TagNameValueHasher, db: SQLiteDatabase, ): String { - val rowIdSubQuery = unionSubqueriesIfNeeded(filters, hasher) + val query = toSql(filters, hasher) + return db.explainQuery(query.sql, query.args.toTypedArray()) + } - return if (rowIdSubQuery == null) { - val query = makeEverythingQuery() - db.explainQuery(query) + fun toSql( + filter: Filter, + hasher: TagNameValueHasher, + ): QuerySpec { + val rowIdSubqueries = prepareRowIDSubQueries(filter, hasher) + + return if (rowIdSubqueries == null) { + QuerySpec( + makeEverythingQuery(), + emptyList(), + ) } else { - val query = makeQueryIn(rowIdSubQuery.sql) - db.explainQuery(query, rowIdSubQuery.args.toTypedArray()) + QuerySpec( + makeQueryIn(rowIdSubqueries.sql), + rowIdSubqueries.args, + ) } } - fun query( + fun toSql( filters: List, - db: SQLiteDatabase, - ): List { - val rowIdSubqueries = unionSubqueriesIfNeeded(filters, hasher(db)) ?: return db.runQuery(makeEverythingQuery()) - return db.runQuery(makeQueryIn(rowIdSubqueries.sql), rowIdSubqueries.args) - } + hasher: TagNameValueHasher, + ): QuerySpec { + val rowIdSubqueries = unionSubqueriesIfNeeded(filters, hasher) - fun query( - filters: List, - db: SQLiteDatabase, - onEach: (T) -> Unit, - ) { - val rowIdSubqueries = unionSubqueriesIfNeeded(filters, hasher(db)) - - if (rowIdSubqueries == null) { - db.runQuery(makeEverythingQuery(), onEach = onEach) + return if (rowIdSubqueries == null) { + QuerySpec( + makeEverythingQuery(), + emptyList(), + ) } else { - db.runQuery(makeQueryIn(rowIdSubqueries.sql), rowIdSubqueries.args, onEach) + QuerySpec( + makeQueryIn(rowIdSubqueries.sql), + rowIdSubqueries.args, + ) } } @@ -129,11 +155,8 @@ class QueryBuilder( ORDER BY created_at DESC, id """.trimIndent() - private fun SQLiteDatabase.runQuery( - sql: String, - args: List = emptyList(), - ): List = - rawQuery(sql, args.toTypedArray()).use { cursor -> + private fun SQLiteDatabase.runQuery(query: QuerySpec): List = + rawQuery(query.sql, query.args.toTypedArray()).use { cursor -> ArrayList(cursor.count).apply { while (cursor.moveToNext()) { add(cursor.toEvent()) @@ -141,16 +164,33 @@ class QueryBuilder( } } + private fun SQLiteDatabase.runRawQuery(query: QuerySpec): List = + rawQuery(query.sql, query.args.toTypedArray()).use { cursor -> + ArrayList(cursor.count).apply { + while (cursor.moveToNext()) { + add(cursor.toRawEvent()) + } + } + } + private inline fun SQLiteDatabase.runQuery( - sql: String, - args: List = emptyList(), + query: QuerySpec, onEach: (T) -> Unit, - ) = rawQuery(sql, args.toTypedArray()).use { cursor -> + ) = rawQuery(query.sql, query.args.toTypedArray()).use { cursor -> while (cursor.moveToNext()) { onEach(cursor.toEvent()) } } + private inline fun SQLiteDatabase.runRawQuery( + query: QuerySpec, + onEach: (RawEvent) -> Unit, + ) = rawQuery(query.sql, query.args.toTypedArray()).use { cursor -> + while (cursor.moveToNext()) { + onEach(cursor.toRawEvent()) + } + } + private fun Cursor.toEvent() = EventFactory.create( getString(0).intern(), @@ -162,27 +202,6 @@ class QueryBuilder( getString(6), ) - class RawEvent( - val id: HexKey, - val pubKey: HexKey, - val createdAt: Long, - val kind: Kind, - val jsonTags: String, - val content: String, - val sig: HexKey, - ) { - fun toEvent() = - EventFactory.create( - id.intern(), - pubKey.intern(), - createdAt, - kind, - OptimizedJsonMapper.fromJsonToTagArray(jsonTags), - content, - sig, - ) - } - private fun Cursor.toRawEvent() = RawEvent( getString(0), @@ -271,7 +290,7 @@ class QueryBuilder( fun unionSubqueriesIfNeeded( filters: List, hasher: TagNameValueHasher, - ): RowIdSubQuery? { + ): QuerySpec? { val inner = filters.mapNotNull { filter -> prepareRowIDSubQueries(filter, hasher) @@ -282,7 +301,7 @@ class QueryBuilder( return if (inner.size == 1) { inner.first() } else { - RowIdSubQuery( + QuerySpec( sql = inner.joinToString("\n UNION\n ") { "SELECT row_id FROM (${it.sql})" }, args = inner.flatMap { it.args }, ) @@ -306,7 +325,7 @@ class QueryBuilder( fun prepareRowIDSubQueries( filter: Filter, hasher: TagNameValueHasher, - ): RowIdSubQuery? { + ): QuerySpec? { if (!filter.isFilledFilter()) return null val mustJoinSearch = (filter.search != null) @@ -457,10 +476,10 @@ class QueryBuilder( clause.conditions } - return RowIdSubQuery("$projection WHERE $whereClause", clause.args) + return QuerySpec("$projection WHERE $whereClause", clause.args) } - data class RowIdSubQuery( + data class QuerySpec( val sql: String, val args: List, ) diff --git a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/SQLiteEventStore.kt b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/SQLiteEventStore.kt index c51d50753..f7faf6792 100644 --- a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/SQLiteEventStore.kt +++ b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/SQLiteEventStore.kt @@ -27,10 +27,13 @@ import android.database.sqlite.SQLiteOpenHelper import androidx.core.database.sqlite.transaction import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.HexKey +import com.vitorpamplona.quartz.nip01Core.core.Kind +import com.vitorpamplona.quartz.nip01Core.core.OptimizedJsonMapper import com.vitorpamplona.quartz.nip01Core.core.isEphemeral import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter import com.vitorpamplona.quartz.nip01Core.store.IEventStore import com.vitorpamplona.quartz.nip40Expiration.isExpired +import com.vitorpamplona.quartz.utils.EventFactory import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext @@ -187,6 +190,20 @@ class SQLiteEventStore( onEach: (T) -> Unit, ) = queryBuilder.query(filters, readableDatabase, onEach) + fun rawQuery(filter: Filter): List = queryBuilder.rawQuery(filter, readableDatabase) + + fun rawQuery(filters: List): List = queryBuilder.rawQuery(filters, readableDatabase) + + fun rawQuery( + filter: Filter, + onEach: (RawEvent) -> Unit, + ) = queryBuilder.rawQuery(filter, readableDatabase, onEach) + + fun rawQuery( + filters: List, + onEach: (RawEvent) -> Unit, + ) = queryBuilder.rawQuery(filters, readableDatabase, onEach) + fun count(filter: Filter): Int = queryBuilder.count(filter, readableDatabase) fun count(filters: List): Int = queryBuilder.count(filters, readableDatabase) @@ -203,3 +220,24 @@ class SQLiteEventStore( fun deleteExpiredEvents() = expirationModule.deleteExpiredEvents(writableDatabase) } + +class RawEvent( + val id: HexKey, + val pubKey: HexKey, + val createdAt: Long, + val kind: Kind, + val jsonTags: String, + val content: String, + val sig: HexKey, +) { + fun toEvent() = + EventFactory.create( + id.intern(), + pubKey.intern(), + createdAt, + kind, + OptimizedJsonMapper.fromJsonToTagArray(jsonTags), + content, + sig, + ) +} From 5d7c84d35716f64c07a3da4fd71c68b8a4015680 Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Wed, 31 Dec 2025 16:53:41 -0500 Subject: [PATCH 11/63] Setting higher cache size --- .../quartz/nip01Core/store/sqlite/SQLiteEventStore.kt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/SQLiteEventStore.kt b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/SQLiteEventStore.kt index f7faf6792..e1854e344 100644 --- a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/SQLiteEventStore.kt +++ b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/SQLiteEventStore.kt @@ -78,6 +78,9 @@ class SQLiteEventStore( override fun onConfigure(db: SQLiteDatabase) { super.onConfigure(db) + // 32MB memory cache + db.execSQL("PRAGMA cache_size=-32000;") + // makes sure the FKs are sane db.setForeignKeyConstraintsEnabled(true) @@ -87,7 +90,7 @@ class SQLiteEventStore( // The DB can be corrupted if the OS is shutdown before sync, which generally // doesn't happen on Android - db.execSQL("PRAGMA synchronous = OFF") + db.execSQL("PRAGMA synchronous = OFF;") } override fun onCreate(db: SQLiteDatabase) { From 393366d9cc7d9320079b3b40c3a120f3a8c94e75 Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Wed, 31 Dec 2025 18:41:20 -0500 Subject: [PATCH 12/63] Adds size of the DB as a function to the lib --- .../quartz/nip01Core/store/sqlite/SQLiteEventStore.kt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/SQLiteEventStore.kt b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/SQLiteEventStore.kt index e1854e344..3796b019d 100644 --- a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/SQLiteEventStore.kt +++ b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/SQLiteEventStore.kt @@ -93,6 +93,13 @@ class SQLiteEventStore( db.execSQL("PRAGMA synchronous = OFF;") } + fun dbSizeMB(): Int { + val f1 = context.getDatabasePath(dbName) + val f2 = context.getDatabasePath("$dbName-wal") + val total = f1.length() + f2.length() + return (total / (1024 * 1024)).toInt() + } + override fun onCreate(db: SQLiteDatabase) { modules.forEach { it.create(db) From 6553012372421af13f6a5df20929057b61fc5720 Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Thu, 1 Jan 2026 12:22:07 -0500 Subject: [PATCH 13/63] Uses aliases for the Filter class --- .../quartz/nip01Core/relay/filters/Filter.kt | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/filters/Filter.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/filters/Filter.kt index 2d1fb0188..2feae643c 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/filters/Filter.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/filters/Filter.kt @@ -22,6 +22,8 @@ package com.vitorpamplona.quartz.nip01Core.relay.filters import com.vitorpamplona.quartz.nip01Core.core.Address import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.core.HexKey +import com.vitorpamplona.quartz.nip01Core.core.Kind import com.vitorpamplona.quartz.nip01Core.core.OptimizedJsonMapper import com.vitorpamplona.quartz.nip01Core.core.OptimizedSerializable import com.vitorpamplona.quartz.utils.Log @@ -44,9 +46,9 @@ import com.vitorpamplona.quartz.utils.Log * follow Nostr requirements (64-char hex, onion addresses) and logs errors for invalid inputs. */ class Filter( - val ids: List? = null, - val authors: List? = null, - val kinds: List? = null, + val ids: List? = null, + val authors: List? = null, + val kinds: List? = null, val tags: Map>? = null, val tagsAll: Map>? = null, val since: Long? = null, From 90f38c3a588f86e6ea19fa8385f4dc2af60f0084 Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Thu, 1 Jan 2026 12:22:20 -0500 Subject: [PATCH 14/63] adds a isRegular filter for the Kind alias --- .../kotlin/com/vitorpamplona/quartz/nip01Core/core/Kind.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/core/Kind.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/core/Kind.kt index 0aea6ba6f..7bf8cefb3 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/core/Kind.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/core/Kind.kt @@ -25,6 +25,8 @@ import com.vitorpamplona.quartz.nip02FollowList.ContactListEvent typealias Kind = Int +fun Kind.isRegular() = this > 0 && this != ContactListEvent.KIND && this < 10_000 + fun Kind.isEphemeral() = this >= 20_000 && this < 30_000 fun Kind.isReplaceable() = this == MetadataEvent.KIND || this == ContactListEvent.KIND || (this >= 10_000 && this < 20_000) From 507256e0dd419fecffbd5cfa5693a6355dc4e033 Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Thu, 1 Jan 2026 12:36:26 -0500 Subject: [PATCH 15/63] Fixes Or builder --- .../store/sqlite/sql/WhereClauseBuilder.kt | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/sql/WhereClauseBuilder.kt b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/sql/WhereClauseBuilder.kt index 817ab0ea2..ad2edfb5c 100644 --- a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/sql/WhereClauseBuilder.kt +++ b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/sql/WhereClauseBuilder.kt @@ -86,7 +86,7 @@ class WhereClauseBuilder { fun and(block: WhereClauseBuilder.() -> Unit) = apply { val builder = WhereClauseBuilder().apply(block) - val builtCondition = builder.build() + val builtCondition = builder.buildAnd() if (builtCondition != null) { conditions.add(builtCondition) } @@ -95,22 +95,29 @@ class WhereClauseBuilder { fun or(block: WhereClauseBuilder.() -> Unit) = apply { val builder = WhereClauseBuilder().apply(block) - val builtCondition = builder.build() + val builtCondition = builder.buildOr() if (builtCondition != null) { conditions.add(builtCondition) } } - fun build(): Condition? = + fun buildAnd(): Condition? = when (conditions.size) { 0 -> null 1 -> conditions.first() else -> Condition.And(conditions.toList()) } + + fun buildOr(): Condition? = + when (conditions.size) { + 0 -> null + 1 -> conditions.first() + else -> Condition.Or(conditions.toList()) + } } fun where(block: WhereClauseBuilder.() -> Unit): WhereClause { - val condition = WhereClauseBuilder().apply(block).build() ?: Condition.And(emptyList()) + val condition = WhereClauseBuilder().apply(block).buildAnd() ?: Condition.And(emptyList()) return SqlSelectionBuilder(condition).build() } From 1978c8e17eb11f870bbb0be6c50eab6d0266bd85 Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Thu, 1 Jan 2026 12:37:13 -0500 Subject: [PATCH 16/63] Faster way of coding equals to null in the sql builder --- .../store/sqlite/sql/SqlSelectionBuilder.kt | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/sql/SqlSelectionBuilder.kt b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/sql/SqlSelectionBuilder.kt index 7e898c244..59c2946f0 100644 --- a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/sql/SqlSelectionBuilder.kt +++ b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/sql/SqlSelectionBuilder.kt @@ -39,12 +39,20 @@ class SqlSelectionBuilder( private fun buildCondition(cond: Condition): String = when (cond) { is Condition.Equals -> { - selectionArgs.add(cond.value.toString()) - "${cond.column} = ?" + if (cond.value == null) { + "${cond.column} IS NULL" + } else { + selectionArgs.add(cond.value.toString()) + "${cond.column} = ?" + } } is Condition.NotEquals -> { - selectionArgs.add(cond.value.toString()) - "${cond.column} != ?" + if (cond.value == null) { + "${cond.column} IS NULL" + } else { + selectionArgs.add(cond.value.toString()) + "${cond.column} != ?" + } } is Condition.GreaterThan -> { selectionArgs.add(cond.value.toString()) From 9d67d5d6dc9800d25f3964ee04b67e1b8c1f06cb Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Thu, 1 Jan 2026 12:37:32 -0500 Subject: [PATCH 17/63] Implements a raw add on to the query builder --- .../quartz/nip01Core/store/sqlite/sql/Condition.kt | 4 ++++ .../quartz/nip01Core/store/sqlite/sql/SqlSelectionBuilder.kt | 3 +++ .../quartz/nip01Core/store/sqlite/sql/WhereClauseBuilder.kt | 2 ++ 3 files changed, 9 insertions(+) diff --git a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/sql/Condition.kt b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/sql/Condition.kt index c2cd3a6e6..738cef423 100644 --- a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/sql/Condition.kt +++ b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/sql/Condition.kt @@ -21,6 +21,10 @@ package com.vitorpamplona.quartz.nip01Core.store.sqlite.sql sealed class Condition { + data class Raw( + val condition: String, + ) : Condition() + data class Equals( val column: String, val value: Any?, diff --git a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/sql/SqlSelectionBuilder.kt b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/sql/SqlSelectionBuilder.kt index 59c2946f0..78606720d 100644 --- a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/sql/SqlSelectionBuilder.kt +++ b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/sql/SqlSelectionBuilder.kt @@ -38,6 +38,9 @@ class SqlSelectionBuilder( */ private fun buildCondition(cond: Condition): String = when (cond) { + is Condition.Raw -> { + cond.condition + } is Condition.Equals -> { if (cond.value == null) { "${cond.column} IS NULL" diff --git a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/sql/WhereClauseBuilder.kt b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/sql/WhereClauseBuilder.kt index ad2edfb5c..1a42921f6 100644 --- a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/sql/WhereClauseBuilder.kt +++ b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/sql/WhereClauseBuilder.kt @@ -23,6 +23,8 @@ package com.vitorpamplona.quartz.nip01Core.store.sqlite.sql class WhereClauseBuilder { private val conditions = mutableListOf() + fun raw(condition: String) = apply { conditions.add(Condition.Raw(condition)) } + fun equals( column: String, value: Any?, From 45df452a38ff0398eaba3bebbcb2e1d7eddb4e2c Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Thu, 1 Jan 2026 12:37:54 -0500 Subject: [PATCH 18/63] Adds stable to the desktop account manager --- .../vitorpamplona/amethyst/commons/account/AccountManager.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/commons/src/jvmAndroid/kotlin/com/vitorpamplona/amethyst/commons/account/AccountManager.kt b/commons/src/jvmAndroid/kotlin/com/vitorpamplona/amethyst/commons/account/AccountManager.kt index 6fb4df3e3..777bf0f2e 100644 --- a/commons/src/jvmAndroid/kotlin/com/vitorpamplona/amethyst/commons/account/AccountManager.kt +++ b/commons/src/jvmAndroid/kotlin/com/vitorpamplona/amethyst/commons/account/AccountManager.kt @@ -20,6 +20,7 @@ */ package com.vitorpamplona.amethyst.commons.account +import androidx.compose.runtime.Stable import com.vitorpamplona.quartz.nip01Core.core.hexToByteArray import com.vitorpamplona.quartz.nip01Core.core.toHexKey import com.vitorpamplona.quartz.nip01Core.crypto.KeyPair @@ -45,6 +46,7 @@ sealed class AccountState { ) : AccountState() } +@Stable class AccountManager { private val _accountState = MutableStateFlow(AccountState.LoggedOut) val accountState: StateFlow = _accountState.asStateFlow() From 307703cbb7aa35823ffc495a72f153eed2e7acdf Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Thu, 1 Jan 2026 12:47:35 -0500 Subject: [PATCH 19/63] Explains ID index --- .../quartz/nip01Core/store/sqlite/EventIndexesModule.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/EventIndexesModule.kt b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/EventIndexesModule.kt index e8410d5a5..c30fda299 100644 --- a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/EventIndexesModule.kt +++ b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/EventIndexesModule.kt @@ -63,6 +63,7 @@ class EventIndexesModule( """.trimIndent(), ) + // queries by ID (load events) db.execSQL("CREATE UNIQUE INDEX event_headers_id ON event_headers (id)") db.execSQL("CREATE INDEX query_by_kind_pubkey_dtag_idx ON event_headers (kind, pubkey, d_tag)") db.execSQL("CREATE INDEX query_by_created_at_id ON event_headers (created_at DESC, id)") From f48eba6a8eb96d3c805149c33698386fa70fbc67 Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Thu, 1 Jan 2026 12:48:22 -0500 Subject: [PATCH 20/63] No need for this index since it will be covered by addressable_idx --- .../quartz/nip01Core/store/sqlite/EventIndexesModule.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/EventIndexesModule.kt b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/EventIndexesModule.kt index c30fda299..035cc0a40 100644 --- a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/EventIndexesModule.kt +++ b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/EventIndexesModule.kt @@ -65,7 +65,6 @@ class EventIndexesModule( // queries by ID (load events) db.execSQL("CREATE UNIQUE INDEX event_headers_id ON event_headers (id)") - db.execSQL("CREATE INDEX query_by_kind_pubkey_dtag_idx ON event_headers (kind, pubkey, d_tag)") db.execSQL("CREATE INDEX query_by_created_at_id ON event_headers (created_at DESC, id)") // need to check if this is actually needed. From b7c7eabf2ac9f2e223784824530e8ec93a2189e3 Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Thu, 1 Jan 2026 12:48:48 -0500 Subject: [PATCH 21/63] Explains limit index --- .../quartz/nip01Core/store/sqlite/EventIndexesModule.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/EventIndexesModule.kt b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/EventIndexesModule.kt index 035cc0a40..bd3d90ef3 100644 --- a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/EventIndexesModule.kt +++ b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/EventIndexesModule.kt @@ -65,6 +65,8 @@ class EventIndexesModule( // queries by ID (load events) db.execSQL("CREATE UNIQUE INDEX event_headers_id ON event_headers (id)") + + // queries by limit (latest records), since, until (sync all) alone db.execSQL("CREATE INDEX query_by_created_at_id ON event_headers (created_at DESC, id)") // need to check if this is actually needed. From 8affb2564b016e5317aaeba169c3a2582a9a4004 Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Thu, 1 Jan 2026 12:49:12 -0500 Subject: [PATCH 22/63] explains the fk index on tags --- .../quartz/nip01Core/store/sqlite/EventIndexesModule.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/EventIndexesModule.kt b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/EventIndexesModule.kt index bd3d90ef3..a7e887c33 100644 --- a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/EventIndexesModule.kt +++ b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/EventIndexesModule.kt @@ -72,6 +72,7 @@ class EventIndexesModule( // need to check if this is actually needed. db.execSQL("CREATE INDEX query_by_created_at_kind_key ON event_headers (created_at DESC, kind, pubkey)") + // makes deletions on the event_header fast db.execSQL("CREATE INDEX fk_event_tags_header_id ON event_tags (event_header_row_id)") // This is a very slow index to build (half the insert time goes here) but it is extremely effective. From aac880c575dce4554697aa9faf6497483c8445ba Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Thu, 1 Jan 2026 12:51:43 -0500 Subject: [PATCH 23/63] Range queries are not effective as the first argument, switching to kind, key, created_at index, which also almost invalidates the need for the Replaceable idx and is only kept for the unique key consistency --- .../nip01Core/store/sqlite/ReplaceableTest.kt | 52 +++++++++---------- .../store/sqlite/EventIndexesModule.kt | 4 +- .../store/sqlite/ReplaceableModule.kt | 3 +- 3 files changed, 27 insertions(+), 32 deletions(-) diff --git a/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/ReplaceableTest.kt b/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/ReplaceableTest.kt index 97c8aa75d..182414ef2 100644 --- a/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/ReplaceableTest.kt +++ b/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/ReplaceableTest.kt @@ -113,17 +113,16 @@ class ReplaceableTest { @Test fun testTriggersIndexUsageKind0() { - val explainer = - db.store.explainQuery( - """ - SELECT * FROM event_headers - WHERE - event_headers.kind = 0 AND - event_headers.pubkey = 'aa' AND - event_headers.created_at < 1766686500 AND - ((event_headers.kind IN (0, 3)) OR (event_headers.kind >= 10000 AND event_headers.kind < 20000)); - """.trimIndent(), - ) + val sql = + """ + SELECT * FROM event_headers + WHERE + event_headers.kind = 0 AND + event_headers.pubkey = 'aa' AND + event_headers.created_at < 1766686500 + """.trimIndent() + + val explainer = db.store.explainQuery(sql) assertEquals( """ @@ -131,9 +130,8 @@ class ReplaceableTest { WHERE event_headers.kind = 0 AND event_headers.pubkey = 'aa' AND - event_headers.created_at < 1766686500 AND - ((event_headers.kind IN (0, 3)) OR (event_headers.kind >= 10000 AND event_headers.kind < 20000)); - └── SEARCH event_headers USING INDEX replaceable_idx (kind=? AND pubkey=?) + event_headers.created_at < 1766686500 + └── SEARCH event_headers USING INDEX query_by_kind_pubkey_created (kind=? AND pubkey=? AND created_at= 10000 AND event_headers.kind < 20000)); - """.trimIndent(), - ) + val sql = + """ + SELECT * FROM event_headers + WHERE + event_headers.kind = 3 AND + event_headers.pubkey = 'aa' AND + event_headers.created_at < 1766686500 + """.trimIndent() + + val explainer = db.store.explainQuery(sql) assertEquals( """ @@ -159,9 +156,8 @@ class ReplaceableTest { WHERE event_headers.kind = 3 AND event_headers.pubkey = 'aa' AND - event_headers.created_at < 1766686500 AND - ((event_headers.kind IN (0, 3)) OR (event_headers.kind >= 10000 AND event_headers.kind < 20000)); - └── SEARCH event_headers USING INDEX replaceable_idx (kind=? AND pubkey=?) + event_headers.created_at < 1766686500 + └── SEARCH event_headers USING INDEX query_by_kind_pubkey_created (kind=? AND pubkey=? AND created_at= 10000 AND event_headers.kind < 20000)); + event_headers.created_at < NEW.created_at; END; """.trimIndent(), ) From f6d920366d51a29ba9e57e0ff4eb8812c65f4de1 Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Thu, 1 Jan 2026 12:53:02 -0500 Subject: [PATCH 24/63] Fixes some of the tests --- .../quartz/nip01Core/store/sqlite/QueryAssemblerTest.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryAssemblerTest.kt b/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryAssemblerTest.kt index 46c836c0d..c2ef8fb7b 100644 --- a/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryAssemblerTest.kt +++ b/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryAssemblerTest.kt @@ -223,7 +223,7 @@ class QueryAssemblerTest { ON event_headers.row_id = filtered.row_id ORDER BY created_at DESC, id ├── CO-ROUTINE filtered - │ ├── SEARCH event_headers USING INDEX query_by_kind_pubkey_dtag_idx (kind=?) + │ ├── SEARCH event_headers USING INDEX query_by_kind_pubkey_created (kind=?) │ └── USE TEMP B-TREE FOR ORDER BY ├── SCAN filtered ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) @@ -254,7 +254,7 @@ class QueryAssemblerTest { ON event_headers.row_id = filtered.row_id ORDER BY created_at DESC, id ├── CO-ROUTINE filtered - │ ├── SEARCH event_headers USING INDEX query_by_kind_pubkey_dtag_idx (kind=?) + │ ├── SEARCH event_headers USING INDEX query_by_kind_pubkey_created (kind=?) │ └── USE TEMP B-TREE FOR ORDER BY ├── SCAN filtered ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) @@ -457,7 +457,7 @@ class QueryAssemblerTest { ON event_headers.row_id = filtered.row_id ORDER BY created_at DESC, id ├── CO-ROUTINE filtered - │ ├── SEARCH event_headers USING INDEX query_by_kind_pubkey_dtag_idx (kind=? AND pubkey=?) + │ ├── SEARCH event_headers USING INDEX query_by_kind_pubkey_created (kind=? AND pubkey=?) │ └── USE TEMP B-TREE FOR ORDER BY ├── SCAN filtered ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) From 238d4e0004e7d2c28ab49d0eee12c5e691b87106 Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Thu, 1 Jan 2026 14:52:11 -0500 Subject: [PATCH 25/63] No need for the fts module anymore --- .../quartz/nip01Core/store/sqlite/EventIndexesModule.kt | 1 - .../quartz/nip01Core/store/sqlite/SQLiteEventStore.kt | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/EventIndexesModule.kt b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/EventIndexesModule.kt index c474b6e11..75e6550f4 100644 --- a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/EventIndexesModule.kt +++ b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/EventIndexesModule.kt @@ -28,7 +28,6 @@ import com.vitorpamplona.quartz.nip01Core.core.OptimizedJsonMapper import com.vitorpamplona.quartz.nip59Giftwrap.wraps.GiftWrapEvent class EventIndexesModule( - val fts: FullTextSearchModule, val hasher: (db: SQLiteDatabase) -> TagNameValueHasher, val tagIndexStrategy: IndexingStrategy = DefaultIndexingStrategy(), ) : IModule { diff --git a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/SQLiteEventStore.kt b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/SQLiteEventStore.kt index 3796b019d..bc9c837e4 100644 --- a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/SQLiteEventStore.kt +++ b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/SQLiteEventStore.kt @@ -50,7 +50,7 @@ class SQLiteEventStore( val seedModule = SeedModule() val fullTextSearchModule = FullTextSearchModule() - val eventIndexModule = EventIndexesModule(fullTextSearchModule, seedModule::hasher, tagIndexStrategy) + val eventIndexModule = EventIndexesModule(seedModule::hasher, tagIndexStrategy) val replaceableModule = ReplaceableModule() val addressableModule = AddressableModule() From 291db1f30b7c15f8a3a2419b82a7a75bf9b0b9f1 Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Thu, 1 Jan 2026 14:57:48 -0500 Subject: [PATCH 26/63] duplicates kinds and pubkey on the tags table to take complex queries under 100 microseconds --- .../nip01Core/store/sqlite/DeletionTest.kt | 8 +- .../store/sqlite/QueryAssemblerTest.kt | 182 ++++++++++++++++-- .../store/sqlite/DeletionRequestModule.kt | 8 +- .../store/sqlite/EventIndexesModule.kt | 14 +- .../nip01Core/store/sqlite/QueryBuilder.kt | 39 ++-- 5 files changed, 207 insertions(+), 44 deletions(-) diff --git a/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/DeletionTest.kt b/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/DeletionTest.kt index bb35f07be..064024322 100644 --- a/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/DeletionTest.kt +++ b/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/DeletionTest.kt @@ -227,9 +227,9 @@ class DeletionTest { ON event_headers.row_id = event_tags.event_header_row_id WHERE event_tags.tag_hash IN (3221122, 223322) AND - event_tags.created_at >= 1766686500 AND - event_headers.kind = 5 AND - event_headers.pubkey_owner_hash = 22332323 + event_tags.kind = 5 AND + event_tags.pubkey_hash = 22332323 AND + event_tags.created_at >= 1766686500 """.trimIndent() val explainer = @@ -238,7 +238,7 @@ class DeletionTest { TestCase.assertEquals( """ ${sql.replace("\n","\n ")} - ├── SEARCH event_tags USING INDEX query_by_tags_hash (tag_hash=? AND created_at>?) + ├── SEARCH event_tags USING INDEX query_by_tags_hash_kind_pubkey (tag_hash=? AND kind=? AND pubkey_hash=? AND created_at>?) └── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) """.trimIndent(), explainer, diff --git a/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryAssemblerTest.kt b/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryAssemblerTest.kt index c2ef8fb7b..05f30020c 100644 --- a/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryAssemblerTest.kt +++ b/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryAssemblerTest.kt @@ -22,8 +22,13 @@ package com.vitorpamplona.quartz.nip01Core.store.sqlite import android.content.Context import androidx.test.core.app.ApplicationProvider +import com.vitorpamplona.quartz.experimental.relationshipStatus.ContactCardEvent +import com.vitorpamplona.quartz.nip01Core.metadata.MetadataEvent import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter import com.vitorpamplona.quartz.nip02FollowList.ContactListEvent +import com.vitorpamplona.quartz.nip37Drafts.DraftWrapEvent +import com.vitorpamplona.quartz.nip50Search.SearchRelayListEvent +import com.vitorpamplona.quartz.nip65RelayList.AdvertisedRelayListEvent import junit.framework.TestCase import junit.framework.TestCase.assertEquals import org.junit.After @@ -82,13 +87,12 @@ class QueryAssemblerTest { """ SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers INNER JOIN ( - SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags INNER JOIN event_headers ON event_headers.row_id = event_tags.event_header_row_id WHERE (event_tags.tag_hash = "2657743813502222172") AND (event_tags.created_at >= "1750889190") AND (event_headers.kind = "5") AND (event_headers.pubkey = "7c5eb72a4584fdaaeaa145b25c92ea9917704224951219dbd43acef9e91fb88d") + SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags WHERE (event_tags.tag_hash = "2657743813502222172") AND (event_tags.kind = "5") AND (event_tags.pubkey_hash = "1730514094536529999") AND (event_tags.created_at >= "1750889190") ) AS filtered ON event_headers.row_id = filtered.row_id ORDER BY created_at DESC, id ├── CO-ROUTINE filtered - │ ├── SEARCH event_tags USING INDEX query_by_tags_hash (tag_hash=? AND created_at>?) - │ ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) + │ ├── SEARCH event_tags USING INDEX query_by_tags_hash_kind_pubkey (tag_hash=? AND kind=? AND pubkey_hash=? AND created_at>?) │ └── USE TEMP B-TREE FOR DISTINCT ├── SCAN filtered ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) @@ -280,13 +284,12 @@ class QueryAssemblerTest { """ SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers INNER JOIN ( - SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags INNER JOIN event_headers ON event_headers.row_id = event_tags.event_header_row_id WHERE (event_tags.tag_hash = "-4551135004136952885") AND (event_headers.kind = "3") ORDER BY event_tags.created_at DESC LIMIT 30 + SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags WHERE (event_tags.tag_hash = "-4551135004136952885") AND (event_tags.kind = "3") ORDER BY event_tags.created_at DESC LIMIT 30 ) AS filtered ON event_headers.row_id = filtered.row_id ORDER BY created_at DESC, id ├── CO-ROUTINE filtered - │ ├── SEARCH event_tags USING INDEX query_by_tags_hash (tag_hash=?) - │ ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) + │ ├── SEARCH event_tags USING INDEX query_by_tags_hash_kind (tag_hash=? AND kind=?) │ └── USE TEMP B-TREE FOR DISTINCT ├── SCAN filtered ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) @@ -342,13 +345,12 @@ class QueryAssemblerTest { """ SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers INNER JOIN ( - SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags INNER JOIN event_headers ON event_headers.row_id = event_tags.event_header_row_id WHERE (event_tags.tag_hash = "-4551135004136952885") AND (event_headers.kind = "3") ORDER BY event_tags.created_at DESC LIMIT 30 + SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags WHERE (event_tags.tag_hash = "-4551135004136952885") AND (event_tags.kind = "3") ORDER BY event_tags.created_at DESC LIMIT 30 ) AS filtered ON event_headers.row_id = filtered.row_id ORDER BY created_at DESC, id ├── CO-ROUTINE filtered - │ ├── SEARCH event_tags USING INDEX query_by_tags_hash (tag_hash=?) - │ ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) + │ ├── SEARCH event_tags USING INDEX query_by_tags_hash_kind (tag_hash=? AND kind=?) │ └── USE TEMP B-TREE FOR DISTINCT ├── SCAN filtered ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) @@ -374,13 +376,12 @@ class QueryAssemblerTest { """ SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers INNER JOIN ( - SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags INNER JOIN event_headers ON event_headers.row_id = event_tags.event_header_row_id WHERE (event_tags.tag_hash = "-4551135004136952885") AND (event_headers.pubkey = "7c5eb72a4584fdaaeaa145b25c92ea9917704224951219dbd43acef9e91fb88d") ORDER BY event_tags.created_at DESC LIMIT 30 + SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags WHERE (event_tags.tag_hash = "-4551135004136952885") AND (event_tags.pubkey_hash = "1730514094536529999") ORDER BY event_tags.created_at DESC LIMIT 30 ) AS filtered ON event_headers.row_id = filtered.row_id ORDER BY created_at DESC, id ├── CO-ROUTINE filtered │ ├── SEARCH event_tags USING INDEX query_by_tags_hash (tag_hash=?) - │ ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) │ └── USE TEMP B-TREE FOR DISTINCT ├── SCAN filtered ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) @@ -410,14 +411,13 @@ class QueryAssemblerTest { """ SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers INNER JOIN ( - SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags INNER JOIN event_tags as event_tagsIn1 ON event_tagsIn1.event_header_row_id = event_tags.event_header_row_id AND event_tagsIn1.created_at = event_tags.created_at INNER JOIN event_headers ON event_headers.row_id = event_tags.event_header_row_id WHERE (event_tags.tag_hash = "-4551135004136952885") AND (event_tagsIn1.tag_hash = "-6379614208644810021") AND (event_headers.kind = "1") ORDER BY event_tags.created_at DESC LIMIT 30 + SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags INNER JOIN event_tags as event_tagsIn1 ON event_tagsIn1.event_header_row_id = event_tags.event_header_row_id AND event_tagsIn1.created_at = event_tags.created_at WHERE (event_tags.tag_hash = "-4551135004136952885") AND (event_tagsIn1.tag_hash = "-6379614208644810021") AND (event_tags.kind = "1") ORDER BY event_tags.created_at DESC LIMIT 30 ) AS filtered ON event_headers.row_id = filtered.row_id ORDER BY created_at DESC, id ├── CO-ROUTINE filtered - │ ├── SEARCH event_tags USING INDEX query_by_tags_hash (tag_hash=?) - │ ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) - │ ├── SEARCH event_tagsIn1 USING INDEX query_by_tags_hash (tag_hash=? AND event_header_row_id=?) + │ ├── SEARCH event_tags USING INDEX query_by_tags_hash_kind (tag_hash=? AND kind=?) + │ ├── SEARCH event_tagsIn1 USING INDEX query_by_tags_hash (tag_hash=? AND created_at=?) │ └── USE TEMP B-TREE FOR DISTINCT ├── SCAN filtered ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) @@ -519,7 +519,7 @@ class QueryAssemblerTest { ON event_headers.row_id = filtered.row_id ORDER BY created_at DESC, id ├── CO-ROUTINE filtered - │ ├── SEARCH event_tags USING INDEX query_by_tags_hash (tag_hash=?) + │ ├── SEARCH event_tags USING INDEX query_by_tags_hash_kind (tag_hash=?) │ ├── SEARCH event_tagsAll0_1 USING INDEX query_by_tags_hash (tag_hash=? AND created_at=?) │ └── USE TEMP B-TREE FOR DISTINCT ├── SCAN filtered @@ -548,13 +548,12 @@ class QueryAssemblerTest { """ SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers INNER JOIN ( - SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags INNER JOIN event_headers ON event_headers.row_id = event_tags.event_header_row_id WHERE (event_tags.tag_hash = "-4551135004136952885") AND (event_headers.kind = "3") AND (event_headers.pubkey = "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c") ORDER BY event_tags.created_at DESC LIMIT 500 + SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags WHERE (event_tags.tag_hash = "-4551135004136952885") AND (event_tags.kind = "3") AND (event_tags.pubkey_hash = "5446767199141196776") ORDER BY event_tags.created_at DESC LIMIT 500 ) AS filtered ON event_headers.row_id = filtered.row_id ORDER BY created_at DESC, id ├── CO-ROUTINE filtered - │ ├── SEARCH event_tags USING INDEX query_by_tags_hash (tag_hash=?) - │ ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) + │ ├── SEARCH event_tags USING INDEX query_by_tags_hash_kind_pubkey (tag_hash=? AND kind=? AND pubkey_hash=?) │ └── USE TEMP B-TREE FOR DISTINCT ├── SCAN filtered ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) @@ -563,4 +562,149 @@ class QueryAssemblerTest { sql, ) } + + @Test + fun testFollowersSinceNov2025() { + val sql = + explain( + Filter( + kinds = listOf(ContactListEvent.KIND), + tags = + mapOf( + "p" to listOf("460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c"), + ), + since = 1764553447, // Nov 2025 + ), + ) + println(sql) + assertEquals( + """ + SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers + INNER JOIN ( + SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags WHERE (event_tags.tag_hash = "-4551135004136952885") AND (event_tags.kind = "3") AND (event_tags.created_at >= "1764553447") + ) AS filtered + ON event_headers.row_id = filtered.row_id + ORDER BY created_at DESC, id + ├── CO-ROUTINE filtered + │ ├── SEARCH event_tags USING INDEX query_by_tags_hash_kind (tag_hash=? AND kind=? AND created_at>?) + │ └── USE TEMP B-TREE FOR DISTINCT + ├── SCAN filtered + ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) + └── USE TEMP B-TREE FOR ORDER BY + """.trimIndent(), + sql, + ) + } + + @Test + fun testAllAddressablesOfAKindDownload() { + val sql = + explain( + Filter( + kinds = listOf(DraftWrapEvent.KIND), + authors = listOf("460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c"), + since = 1764553447, // Nov 2025 + ), + ) + println(sql) + assertEquals( + """ + SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers + INNER JOIN ( + SELECT event_headers.row_id as row_id FROM event_headers WHERE (event_headers.kind = "31234") AND (event_headers.pubkey = "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c") AND (event_headers.created_at >= "1764553447") AND ((event_headers.kind >= 30000 AND event_headers.kind < 40000)) + ) AS filtered + ON event_headers.row_id = filtered.row_id + ORDER BY created_at DESC, id + ├── SEARCH event_headers USING COVERING INDEX query_by_kind_pubkey_created (kind=? AND pubkey=? AND created_at>?) + ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) + └── USE TEMP B-TREE FOR ORDER BY + """.trimIndent(), + sql, + ) + } + + @Test + fun testReplaceablesOfMultipleKindsDownloadByDateLimit() { + val sql = + explain( + Filter( + kinds = listOf(MetadataEvent.KIND, SearchRelayListEvent.KIND, AdvertisedRelayListEvent.KIND), + authors = listOf("460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c"), + limit = 20, + since = 1764553447, // Nov 2025 + ), + ) + assertEquals( + """ + SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers + INNER JOIN ( + SELECT event_headers.row_id as row_id FROM event_headers WHERE (event_headers.kind IN ("0", "10007", "10002")) AND (event_headers.pubkey = "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c") AND (event_headers.created_at >= "1764553447") ORDER BY event_headers.created_at DESC, event_headers.id ASC LIMIT 20 + ) AS filtered + ON event_headers.row_id = filtered.row_id + ORDER BY created_at DESC, id + ├── CO-ROUTINE filtered + │ ├── SEARCH event_headers USING INDEX query_by_kind_pubkey_created (kind=? AND pubkey=? AND created_at>?) + │ └── USE TEMP B-TREE FOR ORDER BY + ├── SCAN filtered + ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) + └── USE TEMP B-TREE FOR ORDER BY + """.trimIndent(), + sql, + ) + } + + @Test + fun testReplaceablesOfMultipleKindsDownload() { + val sql = + explain( + Filter( + kinds = listOf(MetadataEvent.KIND, SearchRelayListEvent.KIND, AdvertisedRelayListEvent.KIND), + authors = listOf("460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c"), + ), + ) + assertEquals( + """ + SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers + INNER JOIN ( + SELECT event_headers.row_id as row_id FROM event_headers WHERE (event_headers.kind IN ("0", "10007", "10002")) AND (event_headers.pubkey = "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c") + ) AS filtered + ON event_headers.row_id = filtered.row_id + ORDER BY created_at DESC, id + ├── SEARCH event_headers USING COVERING INDEX query_by_kind_pubkey_created (kind=? AND pubkey=?) + ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) + └── USE TEMP B-TREE FOR ORDER BY + """.trimIndent(), + sql, + ) + } + + @Test + fun testContactCardDownloadFromTrustedKeys() { + val sql = + explain( + Filter( + kinds = listOf(ContactCardEvent.KIND), + authors = listOf("460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c"), + tags = + mapOf( + "d" to listOf("460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c"), + ), + since = 1764553447, // Nov 2025 + ), + ) + assertEquals( + """ + SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers + INNER JOIN ( + SELECT event_headers.row_id as row_id FROM event_headers WHERE (event_headers.kind = "30382") AND (event_headers.pubkey = "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c") AND (event_headers.d_tag = "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c") AND (event_headers.created_at >= "1764553447") AND ((event_headers.kind >= 30000 AND event_headers.kind < 40000)) + ) AS filtered + ON event_headers.row_id = filtered.row_id + ORDER BY created_at DESC, id + ├── SEARCH event_headers USING INDEX addressable_idx (kind=? AND pubkey=? AND d_tag=?) + ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) + └── USE TEMP B-TREE FOR ORDER BY + """.trimIndent(), + sql, + ) + } } diff --git a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/DeletionRequestModule.kt b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/DeletionRequestModule.kt index de7b13e59..deb4a061d 100644 --- a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/DeletionRequestModule.kt +++ b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/DeletionRequestModule.kt @@ -51,13 +51,11 @@ class DeletionRequestModule( SELECT RAISE(ABORT, 'blocked: a deletion event exists') WHERE EXISTS ( SELECT 1 FROM event_tags - INNER JOIN event_headers - ON event_headers.row_id = event_tags.event_header_row_id WHERE event_tags.tag_hash IN (NEW.etag_hash, NEW.atag_hash) AND - event_tags.created_at >= NEW.created_at AND - event_headers.kind = 5 AND - event_headers.pubkey_owner_hash = NEW.pubkey_owner_hash + event_tags.kind = 5 AND + event_tags.pubkey_hash = NEW.pubkey_owner_hash AND + event_tags.created_at >= NEW.created_at ); END; """.trimIndent(), diff --git a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/EventIndexesModule.kt b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/EventIndexesModule.kt index 75e6550f4..e96c9f93c 100644 --- a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/EventIndexesModule.kt +++ b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/EventIndexesModule.kt @@ -57,6 +57,8 @@ class EventIndexesModule( event_header_row_id INTEGER NOT NULL, tag_hash INTEGER NOT NULL, created_at INTEGER NOT NULL, + kind INTEGER NOT NULL, + pubkey_hash INTEGER NOT NULL, FOREIGN KEY (event_header_row_id) REFERENCES event_headers(row_id) ON DELETE CASCADE ) """.trimIndent(), @@ -74,8 +76,10 @@ class EventIndexesModule( // makes deletions on the event_header fast db.execSQL("CREATE INDEX fk_event_tags_header_id ON event_tags (event_header_row_id)") - // This is a very slow index to build (half the insert time goes here) but it is extremely effective. - db.execSQL("CREATE INDEX query_by_tags_hash ON event_tags (tag_hash, created_at DESC)") + // This is a very slow index to build (80% of the insert time goes here) but it is extremely effective. + db.execSQL("CREATE INDEX query_by_tags_hash ON event_tags (tag_hash, created_at DESC)") + db.execSQL("CREATE INDEX query_by_tags_hash_kind ON event_tags (tag_hash, kind, created_at DESC)") + db.execSQL("CREATE INDEX query_by_tags_hash_kind_pubkey ON event_tags (tag_hash, kind, pubkey_hash, created_at DESC)") // Prevent updates to maintain immutability db.execSQL( @@ -117,9 +121,9 @@ class EventIndexesModule( val sqlInsertTags = """ INSERT OR ROLLBACK INTO event_tags - (event_header_row_id, tag_hash, created_at) + (event_header_row_id, tag_hash, created_at, kind, pubkey_hash) VALUES - (?,?,?) + (?,?,?,?,?) """.trimIndent() fun insert( @@ -178,6 +182,8 @@ class EventIndexesModule( stmtTags.bindLong(1, headerId) stmtTags.bindLong(2, it) stmtTags.bindLong(3, event.createdAt) + stmtTags.bindLong(4, kindLong) + stmtTags.bindLong(5, pubkeyHash) stmtTags.executeInsert() } diff --git a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryBuilder.kt b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryBuilder.kt index 94713826c..0fc2cc569 100644 --- a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryBuilder.kt +++ b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryBuilder.kt @@ -24,6 +24,7 @@ import android.database.Cursor import android.database.sqlite.SQLiteDatabase import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.OptimizedJsonMapper +import com.vitorpamplona.quartz.nip01Core.core.isAddressable import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter import com.vitorpamplona.quartz.nip01Core.store.sqlite.sql.where import com.vitorpamplona.quartz.utils.EventFactory @@ -338,10 +339,7 @@ class QueryBuilder( val needHeaders = with(filter) { - (ids != null) || - (authors != null && authors.isNotEmpty()) || - (kinds != null && kinds.isNotEmpty()) || - (tags != null && tags.containsKey("d")) + (ids != null) || (tags != null && tags.containsKey("d")) } val hasHeaders = @@ -440,20 +438,37 @@ class QueryBuilder( // range search is bad but most of the time these are up the top with few elements. if (reverseLookup) { + filter.kinds?.let { equalsOrIn("event_tags.kind", it) } + filter.authors?.let { equalsOrIn("event_tags.pubkey_hash", it.map { hasher.hash(it) }) } + filter.since?.let { greaterThanOrEquals("event_tags.created_at", it) } filter.until?.let { lessThanOrEquals("event_tags.created_at", it) } + + // there are indexes for these, starting with tags. + filter.tags?.forEach { (tagName, tagValues) -> + if (tagName == "d") { + equalsOrIn("event_headers.d_tag", tagValues) + } + } } else { + filter.kinds?.let { equalsOrIn("event_headers.kind", it) } + filter.authors?.let { equalsOrIn("event_headers.pubkey", it) } + + // there are indexes for these, starting with tags. + filter.tags?.forEach { (tagName, tagValues) -> + if (tagName == "d") { + equalsOrIn("event_headers.d_tag", tagValues) + } + } + filter.since?.let { greaterThanOrEquals("event_headers.created_at", it) } filter.until?.let { lessThanOrEquals("event_headers.created_at", it) } - } - filter.kinds?.let { equalsOrIn("event_headers.kind", it) } - filter.authors?.let { equalsOrIn("event_headers.pubkey", it) } - - // there are indexes for these, starting with tags. - filter.tags?.forEach { (tagName, tagValues) -> - if (tagName == "d") { - equalsOrIn("event_headers.d_tag", tagValues) + // no need to add the replaceable because query_by_kind_pubkey_created already covers it + val isAllAddressable = filter.kinds?.all { it.isAddressable() } ?: false + if (isAllAddressable) { + // matches unique index kind >= 30000 AND kind < 40000 + raw("(event_headers.kind >= 30000 AND event_headers.kind < 40000)") } } From 7b919ba44a68c4c1f3c3da061f6e2f392e3522b8 Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Thu, 1 Jan 2026 15:07:27 -0500 Subject: [PATCH 27/63] added description --- .../com/vitorpamplona/quartz/nip01Core/relay/filters/Filter.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/filters/Filter.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/filters/Filter.kt index 2feae643c..8872600d1 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/filters/Filter.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/filters/Filter.kt @@ -37,6 +37,7 @@ import com.vitorpamplona.quartz.utils.Log * - authors: Optional list of author public keys (must be 64 characters). * - kinds: Optional list of event kinds to include. * - tags: Optional map of tag names to values arrays (common tags like 'p', 'e', 'a' are validated). + * - tagsAll: Optional map of tag names to values arrays that must all match (common tags like 'p', 'e', 'a' are validated). * - since: Optional timestamp for filtering events with publication time ≥ this value. * - until: Optional timestamp for filtering events with publication time ≤ this value. * - limit: Optional maximum number of events to request. From 4c9df0bfef056224a4f5446abfde4208d6a92a3b Mon Sep 17 00:00:00 2001 From: Crowdin Bot Date: Thu, 1 Jan 2026 20:09:47 +0000 Subject: [PATCH 28/63] New Crowdin translations by GitHub Action --- amethyst/src/main/res/values-pl-rPL/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/amethyst/src/main/res/values-pl-rPL/strings.xml b/amethyst/src/main/res/values-pl-rPL/strings.xml index e0303c84f..11b8200fe 100644 --- a/amethyst/src/main/res/values-pl-rPL/strings.xml +++ b/amethyst/src/main/res/values-pl-rPL/strings.xml @@ -158,6 +158,7 @@ Nagraj wiadomość Nagrywanie wiadomości Kliknij i przytrzymaj aby nagrać wiadomość + Nagraj ponownie Nagrywanie Nagrywanie %1$s Wgrywanie… From 7c63d654f2d082f0632a1a6583e3eea9944dd0ff Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Thu, 1 Jan 2026 21:29:20 -0500 Subject: [PATCH 29/63] Inverts the name of the isFilledFilter function --- .../nip01Core/store/sqlite/QueryBuilder.kt | 2 +- .../relay/client/pool/RelayBasedFilter.kt | 6 ++--- .../quartz/nip01Core/relay/filters/Filter.kt | 22 +++++++++---------- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryBuilder.kt b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryBuilder.kt index 0fc2cc569..29bbf3f54 100644 --- a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryBuilder.kt +++ b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryBuilder.kt @@ -327,7 +327,7 @@ class QueryBuilder( filter: Filter, hasher: TagNameValueHasher, ): QuerySpec? { - if (!filter.isFilledFilter()) return null + if (filter.isEmpty()) return null val mustJoinSearch = (filter.search != null) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/pool/RelayBasedFilter.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/pool/RelayBasedFilter.kt index ba5b30576..584df7a8f 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/pool/RelayBasedFilter.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/pool/RelayBasedFilter.kt @@ -35,10 +35,10 @@ class RelayBasedFilter( fun List.groupByRelay(): Map> { val result = mutableMapOf>() for (relayBasedFilter in this) { - if (relayBasedFilter.filter.isFilledFilter()) { - result.getOrPut(relayBasedFilter.relay) { mutableListOf() }.add(relayBasedFilter.filter) - } else { + if (relayBasedFilter.filter.isEmpty()) { Log.e("FilterError", "Ignoring empty filter for ${relayBasedFilter.relay}") + } else { + result.getOrPut(relayBasedFilter.relay) { mutableListOf() }.add(relayBasedFilter.filter) } } return result diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/filters/Filter.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/filters/Filter.kt index 8872600d1..eae7fc8e9 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/filters/Filter.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/filters/Filter.kt @@ -74,18 +74,18 @@ class Filter( ) = Filter(ids, authors, kinds, tags, tagsAll, since, until, limit, search) /** - * Returns true if this filter contains any non-null and non-empty criteria. + * Returns true if this filter doesn't filter for anything. */ - fun isFilledFilter() = - (ids != null && ids.isNotEmpty()) || - (authors != null && authors.isNotEmpty()) || - (kinds != null && kinds.isNotEmpty()) || - (tags != null && tags.isNotEmpty() && tags.values.all { it.isNotEmpty() }) || - (tagsAll != null && tagsAll.isNotEmpty() && tagsAll.values.all { it.isNotEmpty() }) || - (since != null) || - (until != null) || - (limit != null) || - (search != null && search.isNotEmpty()) + fun isEmpty() = + (ids == null || ids.isEmpty()) && + (authors == null || authors.isEmpty()) && + (kinds == null || kinds.isEmpty()) && + (tags == null || tags.isEmpty() && tags.values.all { it.isNotEmpty() }) && + (tagsAll == null || tagsAll.isEmpty() && tagsAll.values.all { it.isNotEmpty() }) && + (since == null) && + (until == null) && + (limit == null) && + (search == null || search.isEmpty()) init { ids?.forEach { From 307cff87e768e045bf39b73e19308a995f13515f Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Fri, 2 Jan 2026 14:54:30 -0500 Subject: [PATCH 30/63] Adds more settings to pick different ways to build the SQL database --- .../nip01Core/store/sqlite/AddressableTest.kt | 166 ++--- .../nip01Core/store/sqlite/BaseDBTest.kt | 57 ++ .../nip01Core/store/sqlite/BasicTest.kt | 308 ++++---- .../nip01Core/store/sqlite/DeletionTest.kt | 664 +++++++++--------- .../nip01Core/store/sqlite/ExpirationTest.kt | 101 ++- .../store/sqlite/FilterMatcherTest.kt | 152 ++-- .../nip01Core/store/sqlite/LargeDBTests.kt | 2 + .../store/sqlite/QueryAssemblerTest.kt | 558 +++++++-------- .../nip01Core/store/sqlite/ReplaceableTest.kt | 219 +++--- .../store/sqlite/RightToVanishTest.kt | 163 ++--- .../nip01Core/store/sqlite/SearchTest.kt | 50 +- .../store/sqlite/EventIndexesModule.kt | 34 +- .../nip01Core/store/sqlite/EventStore.kt | 4 +- .../store/sqlite/IndexingStrategy.kt | 8 +- .../nip01Core/store/sqlite/QueryBuilder.kt | 238 ++++++- .../store/sqlite/SQLiteEventStore.kt | 6 +- .../nip01Core/store/sqlite/sql/Condition.kt | 2 + .../store/sqlite/sql/SqlSelectionBuilder.kt | 3 + .../store/sqlite/sql/WhereClauseBuilder.kt | 2 +- 19 files changed, 1452 insertions(+), 1285 deletions(-) create mode 100644 quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/BaseDBTest.kt diff --git a/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/AddressableTest.kt b/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/AddressableTest.kt index 6214aecc6..d5b2b7ae7 100644 --- a/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/AddressableTest.kt +++ b/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/AddressableTest.kt @@ -20,9 +20,7 @@ */ package com.vitorpamplona.quartz.nip01Core.store.sqlite -import android.content.Context import android.database.sqlite.SQLiteConstraintException -import androidx.test.core.app.ApplicationProvider import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerSync import com.vitorpamplona.quartz.nip23LongContent.LongTextNoteEvent @@ -30,91 +28,91 @@ import com.vitorpamplona.quartz.utils.TimeUtils import junit.framework.TestCase import junit.framework.TestCase.assertEquals import junit.framework.TestCase.fail -import org.junit.After -import org.junit.Before import org.junit.Test -class AddressableTest { - private lateinit var db: EventStore - +class AddressableTest : BaseDBTest() { val signer = NostrSignerSync() - @Before - fun setup() { - val context = ApplicationProvider.getApplicationContext() - db = EventStore(context, null) - } - - @After - fun tearDown() { - db.close() - } - @Test - fun testReplacingAddressables() { - val time = TimeUtils.now() - val version1 = signer.sign(LongTextNoteEvent.build("my cool blog, version 1", "title", dTag = "my-cool-blog", createdAt = time)) - val version2 = signer.sign(LongTextNoteEvent.build("my cool blog, version 2", "title", dTag = "my-cool-blog", createdAt = time + 1)) - val version3 = signer.sign(LongTextNoteEvent.build("my cool blog, version 3", "title", dTag = "my-cool-blog", createdAt = time + 2)) + fun testReplacingAddressables() = + forEachDB { db -> + val time = TimeUtils.now() + val version1 = signer.sign(LongTextNoteEvent.build("my cool blog, version 1", "title", dTag = "my-cool-blog", createdAt = time)) + val version2 = signer.sign(LongTextNoteEvent.build("my cool blog, version 2", "title", dTag = "my-cool-blog", createdAt = time + 1)) + val version3 = signer.sign(LongTextNoteEvent.build("my cool blog, version 3", "title", dTag = "my-cool-blog", createdAt = time + 2)) - val addressableQuery = Filter(kinds = listOf(version1.kind), authors = listOf(version1.pubKey), tags = mapOf("d" to listOf(version1.dTag()))) + val addressableQuery = Filter(kinds = listOf(version1.kind), authors = listOf(version1.pubKey), tags = mapOf("d" to listOf(version1.dTag()))) - db.insert(version1) - - db.assertQuery(version1, Filter(ids = listOf(version1.id))) - db.assertQuery(version1, addressableQuery) - - db.insert(version2) - - db.assertQuery(null, Filter(ids = listOf(version1.id))) - db.assertQuery(version2, Filter(ids = listOf(version2.id))) - db.assertQuery(version2, addressableQuery) - - db.insert(version3) - - db.assertQuery(null, Filter(ids = listOf(version1.id))) - db.assertQuery(null, Filter(ids = listOf(version2.id))) - db.assertQuery(version3, Filter(ids = listOf(version3.id))) - db.assertQuery(version3, addressableQuery) - } - - @Test - fun testBlockingOldAddressables() { - val time = TimeUtils.now() - val version1 = signer.sign(LongTextNoteEvent.build("my cool blog, version 1", "title", dTag = "my-cool-blog", createdAt = time)) - val version2 = signer.sign(LongTextNoteEvent.build("my cool blog, version 2", "title", dTag = "my-cool-blog", createdAt = time + 1)) - val version3 = signer.sign(LongTextNoteEvent.build("my cool blog, version 3", "title", dTag = "my-cool-blog", createdAt = time + 2)) - - val addressableQuery = Filter(kinds = listOf(version1.kind), authors = listOf(version1.pubKey), tags = mapOf("d" to listOf(version1.dTag()))) - - db.insert(version3) - - db.assertQuery(version3, Filter(ids = listOf(version3.id))) - - try { - db.insert(version2) - fail("It should not allow inserting an older version") - } catch (e: Exception) { - TestCase.assertTrue(e is SQLiteConstraintException) - } - - try { db.insert(version1) - fail("It should not allow inserting an older version") - } catch (e: Exception) { - TestCase.assertTrue(e is SQLiteConstraintException) + + db.assertQuery(version1, Filter(ids = listOf(version1.id))) + db.assertQuery(version1, addressableQuery) + + db.insert(version2) + + db.assertQuery(null, Filter(ids = listOf(version1.id))) + db.assertQuery(version2, Filter(ids = listOf(version2.id))) + db.assertQuery(version2, addressableQuery) + + db.insert(version3) + + db.assertQuery(null, Filter(ids = listOf(version1.id))) + db.assertQuery(null, Filter(ids = listOf(version2.id))) + db.assertQuery(version3, Filter(ids = listOf(version3.id))) + db.assertQuery(version3, addressableQuery) } - db.assertQuery(version3, Filter(ids = listOf(version3.id))) - db.assertQuery(version3, addressableQuery) - db.assertQuery(null, Filter(ids = listOf(version2.id))) - db.assertQuery(null, Filter(ids = listOf(version1.id))) - } + @Test + fun testBlockingOldAddressables() = + forEachDB { db -> + val time = TimeUtils.now() + val version1 = signer.sign(LongTextNoteEvent.build("my cool blog, version 1", "title", dTag = "my-cool-blog", createdAt = time)) + val version2 = signer.sign(LongTextNoteEvent.build("my cool blog, version 2", "title", dTag = "my-cool-blog", createdAt = time + 1)) + val version3 = signer.sign(LongTextNoteEvent.build("my cool blog, version 3", "title", dTag = "my-cool-blog", createdAt = time + 2)) + + val addressableQuery = Filter(kinds = listOf(version1.kind), authors = listOf(version1.pubKey), tags = mapOf("d" to listOf(version1.dTag()))) + + db.insert(version3) + + db.assertQuery(version3, Filter(ids = listOf(version3.id))) + + try { + db.insert(version2) + fail("It should not allow inserting an older version") + } catch (e: Exception) { + TestCase.assertTrue(e is SQLiteConstraintException) + } + + try { + db.insert(version1) + fail("It should not allow inserting an older version") + } catch (e: Exception) { + TestCase.assertTrue(e is SQLiteConstraintException) + } + + db.assertQuery(version3, Filter(ids = listOf(version3.id))) + db.assertQuery(version3, addressableQuery) + db.assertQuery(null, Filter(ids = listOf(version2.id))) + db.assertQuery(null, Filter(ids = listOf(version1.id))) + } @Test - fun testTriggersIndexUsage() { - val explainer = - db.store.explainQuery( + fun testTriggersIndexUsage() = + forEachDB { db -> + val explainer = + db.store.explainQuery( + """ + SELECT * FROM event_headers + WHERE + event_headers.kind = 30000 AND + event_headers.pubkey = 'aa' AND + event_headers.d_tag = 'test-tag' AND + event_headers.created_at < 1766686500 AND + event_headers.kind >= 30000 AND event_headers.kind < 40000 + """.trimIndent(), + ) + + assertEquals( """ SELECT * FROM event_headers WHERE @@ -123,21 +121,9 @@ class AddressableTest { event_headers.d_tag = 'test-tag' AND event_headers.created_at < 1766686500 AND event_headers.kind >= 30000 AND event_headers.kind < 40000 + └── SEARCH event_headers USING INDEX addressable_idx (kind=? AND pubkey=? AND d_tag=?) """.trimIndent(), + explainer, ) - - assertEquals( - """ - SELECT * FROM event_headers - WHERE - event_headers.kind = 30000 AND - event_headers.pubkey = 'aa' AND - event_headers.d_tag = 'test-tag' AND - event_headers.created_at < 1766686500 AND - event_headers.kind >= 30000 AND event_headers.kind < 40000 - └── SEARCH event_headers USING INDEX addressable_idx (kind=? AND pubkey=? AND d_tag=?) - """.trimIndent(), - explainer, - ) - } + } } diff --git a/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/BaseDBTest.kt b/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/BaseDBTest.kt new file mode 100644 index 000000000..a1fe2259a --- /dev/null +++ b/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/BaseDBTest.kt @@ -0,0 +1,57 @@ +/** + * Copyright (c) 2025 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip01Core.store.sqlite + +import android.content.Context +import androidx.test.core.app.ApplicationProvider +import org.junit.After +import org.junit.Before + +open class BaseDBTest { + private lateinit var dbs: Map + + @Before + fun setup() { + val context = ApplicationProvider.getApplicationContext() + + dbs = + mapOf( + "Default" to EventStore(context, null, indexStrategy = DefaultIndexingStrategy(false, false)), + "IndexAll" to EventStore(context, null, indexStrategy = DefaultIndexingStrategy(true, false)), + "Order by ID" to EventStore(context, null, indexStrategy = DefaultIndexingStrategy(false, true)), + "IndexAll, Order by ID" to EventStore(context, null, indexStrategy = DefaultIndexingStrategy(true, true)), + ) + } + + @After + fun tearDown() { + dbs.forEach { it.value.close() } + } + + fun forEachDB(action: (EventStore) -> Unit) { + dbs.forEach { + println("--------------------") + println(it.key) + println("--------------------") + action(it.value) + } + } +} diff --git a/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/BasicTest.kt b/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/BasicTest.kt index e0a6537bf..256689628 100644 --- a/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/BasicTest.kt +++ b/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/BasicTest.kt @@ -20,8 +20,6 @@ */ package com.vitorpamplona.quartz.nip01Core.store.sqlite -import android.content.Context -import androidx.test.core.app.ApplicationProvider import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.metadata.MetadataEvent import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter @@ -30,18 +28,14 @@ import com.vitorpamplona.quartz.nip01Core.tags.hashtags.hashtag import com.vitorpamplona.quartz.nip01Core.tags.hashtags.isTaggedHash import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent import com.vitorpamplona.quartz.nip22Comments.CommentEvent -import org.junit.After import org.junit.Assert.assertEquals import org.junit.Assert.assertTrue -import org.junit.Before import org.junit.Test -class BasicTest { - private lateinit var db: SQLiteEventStore - +class BasicTest : BaseDBTest() { val signer = NostrSignerSync() - companion object Companion { + companion object { val profile = MetadataEvent( id = "490d7439e530423f2540d4f2bdb73a0a2935f3df9e1f2a6f699a140c7db311fe", @@ -82,168 +76,166 @@ class BasicTest { ) } - @Before - fun setup() { - val context = ApplicationProvider.getApplicationContext() - db = SQLiteEventStore(context, null) - } - - @After - fun tearDown() { - db.close() - } - @Test - fun testInsertDeleteEvent() { - val note = signer.sign(TextNoteEvent.build("test1")) + fun testInsertDeleteEvent() = + forEachDB { db -> + val note = signer.sign(TextNoteEvent.build("test1")) - db.insertEvent(note) + db.store.insertEvent(note) - db.assertQuery(note, Filter(ids = listOf(note.id))) + db.store.assertQuery(note, Filter(ids = listOf(note.id))) - db.delete(note.id) + db.store.delete(note.id) - db.assertQuery(null, Filter(ids = listOf(note.id))) + db.store.assertQuery(null, Filter(ids = listOf(note.id))) - db.insertEvent(note) + db.store.insertEvent(note) - db.assertQuery(note, Filter(ids = listOf(note.id))) - } - - @Test - fun testEmptyFilter() { - val note1 = signer.sign(TextNoteEvent.build("test1", createdAt = 1)) - val note2 = signer.sign(TextNoteEvent.build("test2", createdAt = 2)) - - db.insertEvent(note1) - - db.assertQuery(note1, Filter()) - - db.insertEvent(note2) - - db.assertQuery(listOf(note2, note1), Filter()) - } - - @Test - fun testLimitFilter() { - val note1 = signer.sign(TextNoteEvent.build("test1", createdAt = 1)) - val note2 = signer.sign(TextNoteEvent.build("test2", createdAt = 2)) - val note3 = signer.sign(TextNoteEvent.build("test3", createdAt = 3)) - val note4 = signer.sign(TextNoteEvent.build("test4", createdAt = 4)) - - db.insertEvent(note1) - - db.assertQuery(note1, Filter(limit = 1)) - - db.insertEvent(note2) - db.insertEvent(note3) - db.insertEvent(note4) - - db.assertQuery(listOf(note4), Filter(limit = 1)) - } - - @Test - fun testPubkeyTag() { - db.insertEvent(comment) - db.insertEvent(profile) - - db.assertQuery( - comment, - Filter(authors = listOf(comment.pubKey), tags = mapOf("I" to listOf("geo:drt3n"))), - ) - } - - @Test - fun testTagOnly() { - db.insertEvent(comment) - db.insertEvent(profile) - - db.assertQuery(comment, Filter(tags = mapOf("I" to listOf("geo:drt3n")))) - } - - @Test - fun testTagWithSinceOnly() { - db.insertEvent(comment) - db.insertEvent(profile) - - db.assertQuery( - comment, - Filter(tags = mapOf("I" to listOf("geo:drt3n")), since = comment.createdAt - 1), - ) - db.assertQuery( - comment, - Filter(tags = mapOf("I" to listOf("geo:drt3n")), since = comment.createdAt), - ) - db.assertQuery( - null, - Filter(tags = mapOf("I" to listOf("geo:drt3n")), since = comment.createdAt + 1), - ) - } - - @Test - fun testTagWithUntilOnly() { - db.insertEvent(comment) - db.insertEvent(profile) - - db.assertQuery( - null, - Filter(tags = mapOf("I" to listOf("geo:drt3n")), until = comment.createdAt - 1), - ) - db.assertQuery( - comment, - Filter(tags = mapOf("I" to listOf("geo:drt3n")), until = comment.createdAt), - ) - db.assertQuery( - comment, - Filter(tags = mapOf("I" to listOf("geo:drt3n")), until = comment.createdAt + 1), - ) - } - - @Test - fun testTagWithUntilOnlyEmitting() { - db.insertEvent(comment) - db.insertEvent(profile) - - db.query(Filter(tags = mapOf("I" to listOf("geo:drt3n")))) { event -> - assertEquals(comment.toJson(), event.toJson()) + db.store.assertQuery(note, Filter(ids = listOf(note.id))) } - } @Test - fun hashCodeTest() { - val note1 = - signer.sign( - TextNoteEvent.build("test1") { - hashtag("AaAa") - }, - ) - val note2 = - signer.sign( - TextNoteEvent.build("test2") { - hashtag("AaAa") - }, - ) - val note3 = - signer.sign( - TextNoteEvent.build("test3") { - hashtag("BBBB") - }, - ) + fun testEmptyFilter() = + forEachDB { db -> + val note1 = signer.sign(TextNoteEvent.build("test1", createdAt = 1)) + val note2 = signer.sign(TextNoteEvent.build("test2", createdAt = 2)) - db.insertEvent(note1) - db.insertEvent(note2) - db.insertEvent(note3) + db.store.insertEvent(note1) - val list = - db.query( - Filter( - tags = mapOf("t" to listOf("AaAa")), - ), - ) + db.store.assertQuery(note1, Filter()) - assertEquals(2, list.size) - list.forEach { - assertTrue(it.isTaggedHash("AaAa")) + db.store.insertEvent(note2) + + db.store.assertQuery(listOf(note2, note1), Filter()) + } + + @Test + fun testLimitFilter() = + forEachDB { db -> + val note1 = signer.sign(TextNoteEvent.build("test1", createdAt = 1)) + val note2 = signer.sign(TextNoteEvent.build("test2", createdAt = 2)) + val note3 = signer.sign(TextNoteEvent.build("test3", createdAt = 3)) + val note4 = signer.sign(TextNoteEvent.build("test4", createdAt = 4)) + + db.store.insertEvent(note1) + + db.store.assertQuery(note1, Filter(limit = 1)) + + db.store.insertEvent(note2) + db.store.insertEvent(note3) + db.store.insertEvent(note4) + + db.store.assertQuery(listOf(note4), Filter(limit = 1)) + } + + @Test + fun testPubkeyTag() = + forEachDB { db -> + db.store.insertEvent(comment) + db.store.insertEvent(profile) + + db.store.assertQuery( + comment, + Filter(authors = listOf(comment.pubKey), tags = mapOf("I" to listOf("geo:drt3n"))), + ) + } + + @Test + fun testTagOnly() = + forEachDB { db -> + db.store.insertEvent(comment) + db.store.insertEvent(profile) + + db.store.assertQuery(comment, Filter(tags = mapOf("I" to listOf("geo:drt3n")))) + } + + @Test + fun testTagWithSinceOnly() = + forEachDB { db -> + db.store.insertEvent(comment) + db.store.insertEvent(profile) + + db.store.assertQuery( + comment, + Filter(tags = mapOf("I" to listOf("geo:drt3n")), since = comment.createdAt - 1), + ) + db.store.assertQuery( + comment, + Filter(tags = mapOf("I" to listOf("geo:drt3n")), since = comment.createdAt), + ) + db.store.assertQuery( + null, + Filter(tags = mapOf("I" to listOf("geo:drt3n")), since = comment.createdAt + 1), + ) + } + + @Test + fun testTagWithUntilOnly() = + forEachDB { db -> + db.store.insertEvent(comment) + db.store.insertEvent(profile) + + db.store.assertQuery( + null, + Filter(tags = mapOf("I" to listOf("geo:drt3n")), until = comment.createdAt - 1), + ) + db.store.assertQuery( + comment, + Filter(tags = mapOf("I" to listOf("geo:drt3n")), until = comment.createdAt), + ) + db.store.assertQuery( + comment, + Filter(tags = mapOf("I" to listOf("geo:drt3n")), until = comment.createdAt + 1), + ) + } + + @Test + fun testTagWithUntilOnlyEmitting() = + forEachDB { db -> + db.store.insertEvent(comment) + db.store.insertEvent(profile) + + db.store.query(Filter(tags = mapOf("I" to listOf("geo:drt3n")))) { event -> + assertEquals(comment.toJson(), event.toJson()) + } + } + + @Test + fun hashCodeTest() = + forEachDB { db -> + val note1 = + signer.sign( + TextNoteEvent.build("test1") { + hashtag("AaAa") + }, + ) + val note2 = + signer.sign( + TextNoteEvent.build("test2") { + hashtag("AaAa") + }, + ) + val note3 = + signer.sign( + TextNoteEvent.build("test3") { + hashtag("BBBB") + }, + ) + + db.store.insertEvent(note1) + db.store.insertEvent(note2) + db.store.insertEvent(note3) + + val list = + db.query( + Filter( + tags = mapOf("t" to listOf("AaAa")), + ), + ) + + assertEquals(2, list.size) + list.forEach { + assertTrue(it.isTaggedHash("AaAa")) + } } - } } diff --git a/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/DeletionTest.kt b/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/DeletionTest.kt index 064024322..9d1ffc3c3 100644 --- a/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/DeletionTest.kt +++ b/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/DeletionTest.kt @@ -20,9 +20,7 @@ */ package com.vitorpamplona.quartz.nip01Core.store.sqlite -import android.content.Context import android.database.sqlite.SQLiteConstraintException -import androidx.test.core.app.ApplicationProvider import com.vitorpamplona.quartz.nip01Core.core.Address import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerSync @@ -33,380 +31,372 @@ import com.vitorpamplona.quartz.nip59Giftwrap.wraps.GiftWrapEvent import com.vitorpamplona.quartz.utils.TimeUtils import junit.framework.TestCase import junit.framework.TestCase.fail -import org.junit.After import org.junit.Assert.assertEquals -import org.junit.Before import org.junit.Test -class DeletionTest { - private lateinit var db: EventStore - +class DeletionTest : BaseDBTest() { val signer = NostrSignerSync() - @Before - fun setup() { - val context = ApplicationProvider.getApplicationContext() - db = EventStore(context, null) - } - - @After - fun tearDown() { - db.close() - } - @Test - fun testInsertDeleteEvent() { - val note1 = signer.sign(TextNoteEvent.build("test1")) - val note2 = signer.sign(TextNoteEvent.build("test2")) - val note3 = signer.sign(TextNoteEvent.build("test3")) + fun testInsertDeleteEvent() = + forEachDB { db -> + val note1 = signer.sign(TextNoteEvent.build("test1")) + val note2 = signer.sign(TextNoteEvent.build("test2")) + val note3 = signer.sign(TextNoteEvent.build("test3")) - db.insert(note1) - db.insert(note2) - db.insert(note3) - - db.assertQuery(note1, Filter(ids = listOf(note1.id))) - db.assertQuery(note2, Filter(ids = listOf(note2.id))) - db.assertQuery(note3, Filter(ids = listOf(note3.id))) - - val deletion = signer.sign(DeletionEvent.build(listOf(note1))) - - db.insert(deletion) - - db.assertQuery(deletion, Filter(ids = listOf(deletion.id))) - db.assertQuery(null, Filter(ids = listOf(note1.id))) - db.assertQuery(note2, Filter(ids = listOf(note2.id))) - db.assertQuery(note3, Filter(ids = listOf(note3.id))) - - // trying to insert again should fail. - try { db.insert(note1) - fail("Should not be able to insert a deleted event") - } catch (e: SQLiteConstraintException) { - assertEquals("blocked: a deletion event exists (code 1811 SQLITE_CONSTRAINT_TRIGGER)", e.message) + db.insert(note2) + db.insert(note3) + + db.assertQuery(note1, Filter(ids = listOf(note1.id))) + db.assertQuery(note2, Filter(ids = listOf(note2.id))) + db.assertQuery(note3, Filter(ids = listOf(note3.id))) + + val deletion = signer.sign(DeletionEvent.build(listOf(note1))) + + db.insert(deletion) + + db.assertQuery(deletion, Filter(ids = listOf(deletion.id))) + db.assertQuery(null, Filter(ids = listOf(note1.id))) + db.assertQuery(note2, Filter(ids = listOf(note2.id))) + db.assertQuery(note3, Filter(ids = listOf(note3.id))) + + // trying to insert again should fail. + try { + db.insert(note1) + fail("Should not be able to insert a deleted event") + } catch (e: SQLiteConstraintException) { + assertEquals("blocked: a deletion event exists (code 1811 SQLITE_CONSTRAINT_TRIGGER)", e.message) + } + + db.assertQuery(deletion, Filter(ids = listOf(deletion.id))) + db.assertQuery(null, Filter(ids = listOf(note1.id))) + db.assertQuery(note2, Filter(ids = listOf(note2.id))) + db.assertQuery(note3, Filter(ids = listOf(note3.id))) } - db.assertQuery(deletion, Filter(ids = listOf(deletion.id))) - db.assertQuery(null, Filter(ids = listOf(note1.id))) - db.assertQuery(note2, Filter(ids = listOf(note2.id))) - db.assertQuery(note3, Filter(ids = listOf(note3.id))) - } - @Test - fun testInsertDeleteEventOfAddressable() { - val time = TimeUtils.now() - val note1 = signer.sign(LongTextNoteEvent.build("my cool blog, version 1", "title", dTag = "my-cool-blog", createdAt = time)) - val note2 = signer.sign(LongTextNoteEvent.build("my cool blog, version 2", "title", dTag = "my-cool-blog", createdAt = time + 1)) - val note3 = signer.sign(LongTextNoteEvent.build("my cool blog, version 3", "title", dTag = "my-cool-blog", createdAt = time + 2)) + fun testInsertDeleteEventOfAddressable() = + forEachDB { db -> + val time = TimeUtils.now() + val note1 = signer.sign(LongTextNoteEvent.build("my cool blog, version 1", "title", dTag = "my-cool-blog", createdAt = time)) + val note2 = signer.sign(LongTextNoteEvent.build("my cool blog, version 2", "title", dTag = "my-cool-blog", createdAt = time + 1)) + val note3 = signer.sign(LongTextNoteEvent.build("my cool blog, version 3", "title", dTag = "my-cool-blog", createdAt = time + 2)) - db.insert(note1) - - db.assertQuery(note1, Filter(ids = listOf(note1.id))) - - db.insert(note2) - - db.assertQuery(null, Filter(ids = listOf(note1.id))) - db.assertQuery(note2, Filter(ids = listOf(note2.id))) - - db.insert(note3) - - db.assertQuery(null, Filter(ids = listOf(note1.id))) - db.assertQuery(null, Filter(ids = listOf(note2.id))) - db.assertQuery(note3, Filter(ids = listOf(note3.id))) - - val deletion = signer.sign(DeletionEvent.build(listOf(note1))) - - db.insert(deletion) - - db.assertQuery(deletion, Filter(ids = listOf(deletion.id))) - db.assertQuery(null, Filter(ids = listOf(note1.id))) - db.assertQuery(null, Filter(ids = listOf(note2.id))) - db.assertQuery(null, Filter(ids = listOf(note3.id))) - - // trying to insert again should fail. - try { db.insert(note1) - fail("Should not be able to insert a deleted event") - } catch (e: SQLiteConstraintException) { - assertEquals("blocked: a deletion event exists (code 1811 SQLITE_CONSTRAINT_TRIGGER)", e.message) + + db.assertQuery(note1, Filter(ids = listOf(note1.id))) + + db.insert(note2) + + db.assertQuery(null, Filter(ids = listOf(note1.id))) + db.assertQuery(note2, Filter(ids = listOf(note2.id))) + + db.insert(note3) + + db.assertQuery(null, Filter(ids = listOf(note1.id))) + db.assertQuery(null, Filter(ids = listOf(note2.id))) + db.assertQuery(note3, Filter(ids = listOf(note3.id))) + + val deletion = signer.sign(DeletionEvent.build(listOf(note1))) + + db.insert(deletion) + + db.assertQuery(deletion, Filter(ids = listOf(deletion.id))) + db.assertQuery(null, Filter(ids = listOf(note1.id))) + db.assertQuery(null, Filter(ids = listOf(note2.id))) + db.assertQuery(null, Filter(ids = listOf(note3.id))) + + // trying to insert again should fail. + try { + db.insert(note1) + fail("Should not be able to insert a deleted event") + } catch (e: SQLiteConstraintException) { + assertEquals("blocked: a deletion event exists (code 1811 SQLITE_CONSTRAINT_TRIGGER)", e.message) + } + + db.assertQuery(deletion, Filter(ids = listOf(deletion.id))) + db.assertQuery(null, Filter(ids = listOf(note1.id))) + db.assertQuery(null, Filter(ids = listOf(note2.id))) + db.assertQuery(null, Filter(ids = listOf(note3.id))) } - db.assertQuery(deletion, Filter(ids = listOf(deletion.id))) - db.assertQuery(null, Filter(ids = listOf(note1.id))) - db.assertQuery(null, Filter(ids = listOf(note2.id))) - db.assertQuery(null, Filter(ids = listOf(note3.id))) - } - @Test - fun testInsertDeleteEventOfAddressable2() { - val time = TimeUtils.now() - val note1 = signer.sign(LongTextNoteEvent.build("my cool blog, version 1", "title", dTag = "my-cool-blog", createdAt = time)) - val note2 = signer.sign(LongTextNoteEvent.build("my cool blog, version 2", "title", dTag = "my-cool-blog", createdAt = time + 1)) - val note3 = signer.sign(LongTextNoteEvent.build("my cool blog, version 3", "title", dTag = "my-cool-blog", createdAt = time + 2)) + fun testInsertDeleteEventOfAddressable2() = + forEachDB { db -> + val time = TimeUtils.now() + val note1 = signer.sign(LongTextNoteEvent.build("my cool blog, version 1", "title", dTag = "my-cool-blog", createdAt = time)) + val note2 = signer.sign(LongTextNoteEvent.build("my cool blog, version 2", "title", dTag = "my-cool-blog", createdAt = time + 1)) + val note3 = signer.sign(LongTextNoteEvent.build("my cool blog, version 3", "title", dTag = "my-cool-blog", createdAt = time + 2)) - db.insert(note1) - db.insert(note2) - db.insert(note3) - - db.assertQuery(null, Filter(ids = listOf(note1.id))) - db.assertQuery(null, Filter(ids = listOf(note2.id))) - db.assertQuery(note3, Filter(ids = listOf(note3.id))) - - val deletion = signer.sign(DeletionEvent.buildAddressOnly(listOf(note1))) - - db.insert(deletion) - - db.assertQuery(deletion, Filter(ids = listOf(deletion.id))) - db.assertQuery(null, Filter(ids = listOf(note1.id))) - db.assertQuery(null, Filter(ids = listOf(note2.id))) - db.assertQuery(null, Filter(ids = listOf(note3.id))) - - // trying to insert again should fail. - try { db.insert(note1) - fail("Should not be able to insert a deleted event") - } catch (e: SQLiteConstraintException) { - assertEquals("blocked: a deletion event exists (code 1811 SQLITE_CONSTRAINT_TRIGGER)", e.message) + db.insert(note2) + db.insert(note3) + + db.assertQuery(null, Filter(ids = listOf(note1.id))) + db.assertQuery(null, Filter(ids = listOf(note2.id))) + db.assertQuery(note3, Filter(ids = listOf(note3.id))) + + val deletion = signer.sign(DeletionEvent.buildAddressOnly(listOf(note1))) + + db.insert(deletion) + + db.assertQuery(deletion, Filter(ids = listOf(deletion.id))) + db.assertQuery(null, Filter(ids = listOf(note1.id))) + db.assertQuery(null, Filter(ids = listOf(note2.id))) + db.assertQuery(null, Filter(ids = listOf(note3.id))) + + // trying to insert again should fail. + try { + db.insert(note1) + fail("Should not be able to insert a deleted event") + } catch (e: SQLiteConstraintException) { + assertEquals("blocked: a deletion event exists (code 1811 SQLITE_CONSTRAINT_TRIGGER)", e.message) + } + + db.assertQuery(deletion, Filter(ids = listOf(deletion.id))) + db.assertQuery(null, Filter(ids = listOf(note1.id))) + db.assertQuery(null, Filter(ids = listOf(note2.id))) + db.assertQuery(null, Filter(ids = listOf(note3.id))) } - db.assertQuery(deletion, Filter(ids = listOf(deletion.id))) - db.assertQuery(null, Filter(ids = listOf(note1.id))) - db.assertQuery(null, Filter(ids = listOf(note2.id))) - db.assertQuery(null, Filter(ids = listOf(note3.id))) - } - @Test - fun testInsertDeleteWrap() { - val me = NostrSignerSync() - val myFriend = NostrSignerSync() + fun testInsertDeleteWrap() = + forEachDB { db -> + val me = NostrSignerSync() + val myFriend = NostrSignerSync() - val note1 = me.sign(TextNoteEvent.build("test1")) - val wrap1 = GiftWrapEvent.create(note1, me.pubKey) - val wrap2 = GiftWrapEvent.create(note1, myFriend.pubKey) + val note1 = me.sign(TextNoteEvent.build("test1")) + val wrap1 = GiftWrapEvent.create(note1, me.pubKey) + val wrap2 = GiftWrapEvent.create(note1, myFriend.pubKey) - db.insert(wrap1) - db.insert(wrap2) - - db.assertQuery(wrap1, Filter(ids = listOf(wrap1.id))) - db.assertQuery(wrap2, Filter(ids = listOf(wrap2.id))) - - val randomDeletionToWrap = signer.sign(DeletionEvent.build(listOf(wrap1))) - - db.insert(randomDeletionToWrap) - - db.assertQuery(randomDeletionToWrap, Filter(ids = listOf(randomDeletionToWrap.id))) - db.assertQuery(wrap1, Filter(ids = listOf(wrap1.id))) - db.assertQuery(wrap2, Filter(ids = listOf(wrap2.id))) - - val deletion = me.sign(DeletionEvent.build(listOf(wrap1))) - - db.insert(deletion) - - db.assertQuery(deletion, Filter(ids = listOf(deletion.id))) - db.assertQuery(null, Filter(ids = listOf(wrap1.id))) - db.assertQuery(wrap2, Filter(ids = listOf(wrap2.id))) - - // trying to insert again should fail. - try { db.insert(wrap1) - fail("Should not be able to insert a deleted event") - } catch (e: SQLiteConstraintException) { - assertEquals("blocked: a deletion event exists (code 1811 SQLITE_CONSTRAINT_TRIGGER)", e.message) + db.insert(wrap2) + + db.assertQuery(wrap1, Filter(ids = listOf(wrap1.id))) + db.assertQuery(wrap2, Filter(ids = listOf(wrap2.id))) + + val randomDeletionToWrap = signer.sign(DeletionEvent.build(listOf(wrap1))) + + db.insert(randomDeletionToWrap) + + db.assertQuery(randomDeletionToWrap, Filter(ids = listOf(randomDeletionToWrap.id))) + db.assertQuery(wrap1, Filter(ids = listOf(wrap1.id))) + db.assertQuery(wrap2, Filter(ids = listOf(wrap2.id))) + + val deletion = me.sign(DeletionEvent.build(listOf(wrap1))) + + db.insert(deletion) + + db.assertQuery(deletion, Filter(ids = listOf(deletion.id))) + db.assertQuery(null, Filter(ids = listOf(wrap1.id))) + db.assertQuery(wrap2, Filter(ids = listOf(wrap2.id))) + + // trying to insert again should fail. + try { + db.insert(wrap1) + fail("Should not be able to insert a deleted event") + } catch (e: SQLiteConstraintException) { + assertEquals("blocked: a deletion event exists (code 1811 SQLITE_CONSTRAINT_TRIGGER)", e.message) + } + + db.assertQuery(deletion, Filter(ids = listOf(deletion.id))) + db.assertQuery(null, Filter(ids = listOf(wrap1.id))) + db.assertQuery(wrap2, Filter(ids = listOf(wrap2.id))) } - db.assertQuery(deletion, Filter(ids = listOf(deletion.id))) - db.assertQuery(null, Filter(ids = listOf(wrap1.id))) - db.assertQuery(wrap2, Filter(ids = listOf(wrap2.id))) - } + @Test + fun testTriggersIndexUsage() = + forEachDB { db -> + val sql = + """ + SELECT 1 FROM event_tags + WHERE + event_tags.tag_hash IN (3221122, 223322) AND + event_tags.kind = 5 AND + event_tags.pubkey_hash = 22332323 AND + event_tags.created_at >= 1766686500 + """.trimIndent() + + val explainer = + db.store.explainQuery(sql) + + TestCase.assertEquals( + """ + ${sql.replace("\n","\n ")} + └── SEARCH event_tags USING COVERING INDEX query_by_tags_hash_kind_pubkey (tag_hash=? AND kind=? AND pubkey_hash=? AND created_at>?) + """.trimIndent(), + explainer, + ) + } @Test - fun testTriggersIndexUsage() { - val sql = - """ - SELECT 1 FROM event_tags - INNER JOIN event_headers - ON event_headers.row_id = event_tags.event_header_row_id - WHERE - event_tags.tag_hash IN (3221122, 223322) AND - event_tags.kind = 5 AND - event_tags.pubkey_hash = 22332323 AND - event_tags.created_at >= 1766686500 - """.trimIndent() + fun testDeleteById() = + forEachDB { db -> + val sql = + db.store.deletionModule + .deleteSQL( + pubkey = "key1", + idValues = listOf("ca29c211f", "ca29c211d"), + addresses = emptyList(), + hasher = TagNameValueHasher(0), + ).first() - val explainer = - db.store.explainQuery(sql) - - TestCase.assertEquals( - """ - ${sql.replace("\n","\n ")} - ├── SEARCH event_tags USING INDEX query_by_tags_hash_kind_pubkey (tag_hash=? AND kind=? AND pubkey_hash=? AND created_at>?) - └── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) - """.trimIndent(), - explainer, - ) - } + TestCase.assertEquals( + """ + DELETE FROM event_headers + WHERE + id IN ("ca29c211f","ca29c211d") AND + pubkey_owner_hash = "1573573083296714675" + ├── SEARCH event_headers USING INDEX event_headers_id (id=?) + ├── SEARCH event_vanish USING INTEGER PRIMARY KEY (rowid=?) + ├── SEARCH event_expirations USING INTEGER PRIMARY KEY (rowid=?) + └── SEARCH event_tags USING COVERING INDEX fk_event_tags_header_id (event_header_row_id=?) + """.trimIndent(), + db.store.explainQuery(sql.sql, sql.args), + ) + } @Test - fun testDeleteById() { - val sql = - db.store.deletionModule - .deleteSQL( - pubkey = "key1", - idValues = listOf("ca29c211f", "ca29c211d"), - addresses = emptyList(), - hasher = TagNameValueHasher(0), - ).first() + fun testDeleteAddressable() = + forEachDB { db -> + val sql = + db.store.deletionModule + .deleteSQL( + pubkey = "key1", + idValues = emptyList(), + addresses = + listOf( + Address(30000, "key1", "a"), + ), + hasher = TagNameValueHasher(0), + ).first() - TestCase.assertEquals( - """ - DELETE FROM event_headers - WHERE - id IN ("ca29c211f","ca29c211d") AND - pubkey_owner_hash = "1573573083296714675" - ├── SEARCH event_headers USING INDEX event_headers_id (id=?) - ├── SEARCH event_vanish USING INTEGER PRIMARY KEY (rowid=?) - ├── SEARCH event_expirations USING INTEGER PRIMARY KEY (rowid=?) - └── SEARCH event_tags USING COVERING INDEX fk_event_tags_header_id (event_header_row_id=?) - """.trimIndent(), - db.store.explainQuery(sql.sql, sql.args), - ) - } + TestCase.assertEquals( + """ + DELETE FROM event_headers + WHERE ( + (kind = "30000" AND pubkey = "key1" AND d_tag = "a") + ) AND + kind >= 30000 AND kind < 40000 + ├── SEARCH event_headers USING COVERING INDEX addressable_idx (kind=? AND pubkey=? AND d_tag=?) + ├── SEARCH event_vanish USING INTEGER PRIMARY KEY (rowid=?) + ├── SEARCH event_expirations USING INTEGER PRIMARY KEY (rowid=?) + └── SEARCH event_tags USING COVERING INDEX fk_event_tags_header_id (event_header_row_id=?) + """.trimIndent(), + db.store.explainQuery(sql.sql, sql.args), + ) + } @Test - fun testDeleteAddressable() { - val sql = - db.store.deletionModule - .deleteSQL( - pubkey = "key1", - idValues = emptyList(), - addresses = - listOf( - Address(30000, "key1", "a"), - ), - hasher = TagNameValueHasher(0), - ).first() + fun testDeleteAddressablesSingleKind() = + forEachDB { db -> + val sql = + db.store.deletionModule + .deleteSQL( + pubkey = "key1", + idValues = emptyList(), + addresses = + listOf( + Address(30000, "key1", "a"), + Address(30000, "key1", "b"), + Address(30000, "key1", "c"), + Address(30000, "key1", "d"), + ), + hasher = TagNameValueHasher(0), + ).first() - TestCase.assertEquals( - """ - DELETE FROM event_headers - WHERE ( - (kind = "30000" AND pubkey = "key1" AND d_tag = "a") - ) AND - kind >= 30000 AND kind < 40000 - ├── SEARCH event_headers USING COVERING INDEX addressable_idx (kind=? AND pubkey=? AND d_tag=?) - ├── SEARCH event_vanish USING INTEGER PRIMARY KEY (rowid=?) - ├── SEARCH event_expirations USING INTEGER PRIMARY KEY (rowid=?) - └── SEARCH event_tags USING COVERING INDEX fk_event_tags_header_id (event_header_row_id=?) - """.trimIndent(), - db.store.explainQuery(sql.sql, sql.args), - ) - } + TestCase.assertEquals( + """ + DELETE FROM event_headers + WHERE ( + (kind = "30000" AND pubkey = "key1" AND d_tag IN ("a","b","c","d")) + ) AND + kind >= 30000 AND kind < 40000 + ├── SEARCH event_headers USING COVERING INDEX addressable_idx (kind=? AND pubkey=? AND d_tag=?) + ├── SEARCH event_vanish USING INTEGER PRIMARY KEY (rowid=?) + ├── SEARCH event_expirations USING INTEGER PRIMARY KEY (rowid=?) + └── SEARCH event_tags USING COVERING INDEX fk_event_tags_header_id (event_header_row_id=?) + """.trimIndent(), + db.store.explainQuery(sql.sql, sql.args), + ) + } @Test - fun testDeleteAddressablesSingleKind() { - val sql = - db.store.deletionModule - .deleteSQL( - pubkey = "key1", - idValues = emptyList(), - addresses = - listOf( - Address(30000, "key1", "a"), - Address(30000, "key1", "b"), - Address(30000, "key1", "c"), - Address(30000, "key1", "d"), - ), - hasher = TagNameValueHasher(0), - ).first() + fun testDeleteAddressablesMultipleKinds() = + forEachDB { db -> + val sql = + db.store.deletionModule + .deleteSQL( + pubkey = "key1", + idValues = emptyList(), + addresses = + listOf( + Address(30000, "key1", "a"), + Address(30000, "key1", "b"), + Address(30101, "key1", "c"), + Address(30101, "key1", "d"), + Address(30001, "key2", "e"), + Address(30001, "key2", "f"), + ), + hasher = TagNameValueHasher(0), + ).first() - TestCase.assertEquals( - """ - DELETE FROM event_headers - WHERE ( - (kind = "30000" AND pubkey = "key1" AND d_tag IN ("a","b","c","d")) - ) AND - kind >= 30000 AND kind < 40000 - ├── SEARCH event_headers USING COVERING INDEX addressable_idx (kind=? AND pubkey=? AND d_tag=?) - ├── SEARCH event_vanish USING INTEGER PRIMARY KEY (rowid=?) - ├── SEARCH event_expirations USING INTEGER PRIMARY KEY (rowid=?) - └── SEARCH event_tags USING COVERING INDEX fk_event_tags_header_id (event_header_row_id=?) - """.trimIndent(), - db.store.explainQuery(sql.sql, sql.args), - ) - } + TestCase.assertEquals( + """ + DELETE FROM event_headers + WHERE ( + (kind = "30000" AND pubkey = "key1" AND d_tag IN ("a","b")) + OR + (kind = "30101" AND pubkey = "key1" AND d_tag IN ("c","d")) + ) AND + kind >= 30000 AND kind < 40000 + ├── MULTI-INDEX OR + │ ├── INDEX 1 + │ │ └── SEARCH event_headers USING COVERING INDEX addressable_idx (kind=? AND pubkey=? AND d_tag=?) + │ └── INDEX 2 + │ └── SEARCH event_headers USING COVERING INDEX addressable_idx (kind=? AND pubkey=? AND d_tag=?) + ├── SEARCH event_vanish USING INTEGER PRIMARY KEY (rowid=?) + ├── SEARCH event_expirations USING INTEGER PRIMARY KEY (rowid=?) + └── SEARCH event_tags USING COVERING INDEX fk_event_tags_header_id (event_header_row_id=?) + """.trimIndent(), + db.store.explainQuery(sql.sql, sql.args), + ) + } @Test - fun testDeleteAddressablesMultipleKinds() { - val sql = - db.store.deletionModule - .deleteSQL( - pubkey = "key1", - idValues = emptyList(), - addresses = - listOf( - Address(30000, "key1", "a"), - Address(30000, "key1", "b"), - Address(30101, "key1", "c"), - Address(30101, "key1", "d"), - Address(30001, "key2", "e"), - Address(30001, "key2", "f"), - ), - hasher = TagNameValueHasher(0), - ).first() + fun testDeleteReplaceables() = + forEachDB { db -> + val sql = + db.store.deletionModule + .deleteSQL( + pubkey = "key1", + idValues = emptyList(), + addresses = + listOf( + Address(10000, "key1", ""), + Address(10000, "key1", ""), + Address(10001, "key1", ""), + Address(10001, "key1", ""), + Address(10001, "key2", ""), + Address(10001, "key2", ""), + ), + hasher = TagNameValueHasher(0), + ).first() - TestCase.assertEquals( - """ - DELETE FROM event_headers - WHERE ( - (kind = "30000" AND pubkey = "key1" AND d_tag IN ("a","b")) - OR - (kind = "30101" AND pubkey = "key1" AND d_tag IN ("c","d")) - ) AND - kind >= 30000 AND kind < 40000 - ├── MULTI-INDEX OR - │ ├── INDEX 1 - │ │ └── SEARCH event_headers USING COVERING INDEX addressable_idx (kind=? AND pubkey=? AND d_tag=?) - │ └── INDEX 2 - │ └── SEARCH event_headers USING COVERING INDEX addressable_idx (kind=? AND pubkey=? AND d_tag=?) - ├── SEARCH event_vanish USING INTEGER PRIMARY KEY (rowid=?) - ├── SEARCH event_expirations USING INTEGER PRIMARY KEY (rowid=?) - └── SEARCH event_tags USING COVERING INDEX fk_event_tags_header_id (event_header_row_id=?) - """.trimIndent(), - db.store.explainQuery(sql.sql, sql.args), - ) - } - - @Test - fun testDeleteReplaceables() { - val sql = - db.store.deletionModule - .deleteSQL( - pubkey = "key1", - idValues = emptyList(), - addresses = - listOf( - Address(10000, "key1", ""), - Address(10000, "key1", ""), - Address(10001, "key1", ""), - Address(10001, "key1", ""), - Address(10001, "key2", ""), - Address(10001, "key2", ""), - ), - hasher = TagNameValueHasher(0), - ).first() - - TestCase.assertEquals( - """ - DELETE FROM event_headers - WHERE - kind IN ("10000","10001") AND - pubkey = "key1" AND - ((kind in (0,3)) OR (kind >= 10000 AND kind < 20000)) - ├── SEARCH event_headers USING COVERING INDEX replaceable_idx (kind=? AND pubkey=?) - ├── SEARCH event_vanish USING INTEGER PRIMARY KEY (rowid=?) - ├── SEARCH event_expirations USING INTEGER PRIMARY KEY (rowid=?) - └── SEARCH event_tags USING COVERING INDEX fk_event_tags_header_id (event_header_row_id=?) - """.trimIndent(), - db.store.explainQuery(sql.sql, sql.args), - ) - } + TestCase.assertEquals( + """ + DELETE FROM event_headers + WHERE + kind IN ("10000","10001") AND + pubkey = "key1" AND + ((kind in (0,3)) OR (kind >= 10000 AND kind < 20000)) + ├── SEARCH event_headers USING COVERING INDEX replaceable_idx (kind=? AND pubkey=?) + ├── SEARCH event_vanish USING INTEGER PRIMARY KEY (rowid=?) + ├── SEARCH event_expirations USING INTEGER PRIMARY KEY (rowid=?) + └── SEARCH event_tags USING COVERING INDEX fk_event_tags_header_id (event_header_row_id=?) + """.trimIndent(), + db.store.explainQuery(sql.sql, sql.args), + ) + } } diff --git a/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/ExpirationTest.kt b/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/ExpirationTest.kt index 6197a8967..0b86746bc 100644 --- a/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/ExpirationTest.kt +++ b/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/ExpirationTest.kt @@ -20,84 +20,69 @@ */ package com.vitorpamplona.quartz.nip01Core.store.sqlite -import android.content.Context import android.database.sqlite.SQLiteConstraintException -import androidx.test.core.app.ApplicationProvider import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerSync import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent import com.vitorpamplona.quartz.nip40Expiration.expiration import com.vitorpamplona.quartz.utils.TimeUtils import junit.framework.TestCase.fail -import org.junit.After import org.junit.Assert.assertTrue -import org.junit.Before import org.junit.Test -class ExpirationTest { - private lateinit var db: EventStore - +class ExpirationTest : BaseDBTest() { val signer = NostrSignerSync() - @Before - fun setup() { - val context = ApplicationProvider.getApplicationContext() - db = EventStore(context, null) - } - - @After - fun tearDown() { - db.close() - } - @Test - fun testDeletingExpiredEvents() { - val time = TimeUtils.now() + fun testDeletingExpiredEvents() = + forEachDB { db -> + val time = TimeUtils.now() - val noteSafe = - signer.sign( - TextNoteEvent.build("test1", createdAt = time + 1) { - expiration(time + 100) - }, - ) + val noteSafe = + signer.sign( + TextNoteEvent.build("test1", createdAt = time + 1) { + expiration(time + 100) + }, + ) - db.insert(noteSafe) + db.insert(noteSafe) - val noteToExpire = - signer.sign( - TextNoteEvent.build("test1", createdAt = time + 1) { - expiration(time + 1) - }, - ) + val noteToExpire = + signer.sign( + TextNoteEvent.build("test1", createdAt = time + 1) { + expiration(time + 1) + }, + ) - db.insert(noteToExpire) + db.insert(noteToExpire) - db.assertQuery(noteToExpire, Filter(ids = listOf(noteToExpire.id))) + db.assertQuery(noteToExpire, Filter(ids = listOf(noteToExpire.id))) - Thread.sleep(2000) + Thread.sleep(2000) - db.deleteExpiredEvents() + db.deleteExpiredEvents() - db.assertQuery(null, Filter(ids = listOf(noteToExpire.id))) - db.assertQuery(noteSafe, Filter(ids = listOf(noteSafe.id))) - } - - @Test - fun testInsertingExpiredEvents() { - val time = TimeUtils.now() - - val note1 = - signer.sign( - TextNoteEvent.build("test1", createdAt = time - 12) { - expiration(time - 10) - }, - ) - - try { - db.insert(note1) - fail("Should not be able to insert expired events") - } catch (e: Exception) { - assertTrue(e is SQLiteConstraintException) + db.assertQuery(null, Filter(ids = listOf(noteToExpire.id))) + db.assertQuery(noteSafe, Filter(ids = listOf(noteSafe.id))) + } + + @Test + fun testInsertingExpiredEvents() = + forEachDB { db -> + val time = TimeUtils.now() + + val note1 = + signer.sign( + TextNoteEvent.build("test1", createdAt = time - 12) { + expiration(time - 10) + }, + ) + + try { + db.insert(note1) + fail("Should not be able to insert expired events") + } catch (e: Exception) { + assertTrue(e is SQLiteConstraintException) + } } - } } diff --git a/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/FilterMatcherTest.kt b/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/FilterMatcherTest.kt index 22f3b5c17..88a53e734 100644 --- a/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/FilterMatcherTest.kt +++ b/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/FilterMatcherTest.kt @@ -20,28 +20,11 @@ */ package com.vitorpamplona.quartz.nip01Core.store.sqlite -import android.content.Context -import androidx.test.core.app.ApplicationProvider import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter -import org.junit.After -import org.junit.Before import org.junit.Test -class FilterMatcherTest { - private lateinit var db: EventStore - - @Before - fun setup() { - val context = ApplicationProvider.getApplicationContext() - db = EventStore(context, null) - } - - @After - fun tearDown() { - db.close() - } - +class FilterMatcherTest : BaseDBTest() { val id = "98b574c3527f0ffb30b7271084e3f07480733c7289f8de424d29eae82e36c758" val pubkey = "46fcbe3065eaf1ae7811465924e48923363ff3f526bd6f73d7c184b16bd8ce4d" val createdAt: Long = 1683596206 @@ -83,91 +66,100 @@ class FilterMatcherTest { ) @Test - fun matchIds() { - db.insert(note) + fun matchIds() = + forEachDB { db -> + db.insert(note) - db.assertQuery(note, Filter(ids = listOf(id))) - db.assertQuery(note, Filter(ids = listOf(id, rootETag))) - db.assertQuery(null, Filter(ids = listOf(rootETag))) - } + db.assertQuery(note, Filter(ids = listOf(id))) + db.assertQuery(note, Filter(ids = listOf(id, rootETag))) + db.assertQuery(null, Filter(ids = listOf(rootETag))) + } @Test - fun matchPubkeys() { - db.insert(note) + fun matchPubkeys() = + forEachDB { db -> + db.insert(note) - db.assertQuery(note, Filter(authors = listOf(pubkey))) - db.assertQuery(note, Filter(authors = listOf(pubkey, rootETag))) - db.assertQuery(null, Filter(authors = listOf(rootETag))) - } + db.assertQuery(note, Filter(authors = listOf(pubkey))) + db.assertQuery(note, Filter(authors = listOf(pubkey, rootETag))) + db.assertQuery(null, Filter(authors = listOf(rootETag))) + } @Test - fun matchTags() { - db.insert(note) + fun matchTags() = + forEachDB { db -> + db.insert(note) - db.assertQuery(note, Filter(tags = mapOf("p" to listOf(pTag1)))) - db.assertQuery(note, Filter(tags = mapOf("p" to listOf(pTag1, pTag2, pTag3)))) - db.assertQuery(note, Filter(tags = mapOf("p" to listOf(pTag1, id)))) - db.assertQuery(null, Filter(tags = mapOf("p" to listOf(id)))) - } + db.assertQuery(note, Filter(tags = mapOf("p" to listOf(pTag1)))) + db.assertQuery(note, Filter(tags = mapOf("p" to listOf(pTag1, pTag2, pTag3)))) + db.assertQuery(note, Filter(tags = mapOf("p" to listOf(pTag1, id)))) + db.assertQuery(null, Filter(tags = mapOf("p" to listOf(id)))) + } @Test - fun matchDualTags() { - db.insert(note) + fun matchDualTags() = + forEachDB { db -> + db.insert(note) - db.assertQuery(note, Filter(tags = mapOf("p" to listOf(pTag1), "e" to listOf(rootETag)))) - db.assertQuery(note, Filter(tags = mapOf("p" to listOf(pTag1, pTag2, pTag3), "e" to listOf(rootETag, replyETag)))) - db.assertQuery(note, Filter(tags = mapOf("p" to listOf(pTag1, id), "e" to listOf(rootETag, replyETag)))) - db.assertQuery(note, Filter(tags = mapOf("p" to listOf(pTag1, id), "e" to listOf(rootETag, pubkey)))) - db.assertQuery(null, Filter(tags = mapOf("p" to listOf(pTag1, id), "e" to listOf(id, pubkey)))) - db.assertQuery(null, Filter(tags = mapOf("p" to listOf(id), "e" to listOf(rootETag)))) - } + db.assertQuery(note, Filter(tags = mapOf("p" to listOf(pTag1), "e" to listOf(rootETag)))) + db.assertQuery(note, Filter(tags = mapOf("p" to listOf(pTag1, pTag2, pTag3), "e" to listOf(rootETag, replyETag)))) + db.assertQuery(note, Filter(tags = mapOf("p" to listOf(pTag1, id), "e" to listOf(rootETag, replyETag)))) + db.assertQuery(note, Filter(tags = mapOf("p" to listOf(pTag1, id), "e" to listOf(rootETag, pubkey)))) + db.assertQuery(null, Filter(tags = mapOf("p" to listOf(pTag1, id), "e" to listOf(id, pubkey)))) + db.assertQuery(null, Filter(tags = mapOf("p" to listOf(id), "e" to listOf(rootETag)))) + } @Test - fun matchAllTags() { - db.insert(note) + fun matchAllTags() = + forEachDB { db -> + db.insert(note) - db.assertQuery(note, Filter(tagsAll = mapOf("p" to listOf(pTag1)))) - db.assertQuery(note, Filter(tagsAll = mapOf("p" to listOf(pTag1, pTag2, pTag3)))) - db.assertQuery(null, Filter(tagsAll = mapOf("p" to listOf(pTag1, id)))) - db.assertQuery(null, Filter(tagsAll = mapOf("p" to listOf(id)))) - } + db.assertQuery(note, Filter(tagsAll = mapOf("p" to listOf(pTag1)))) + db.assertQuery(note, Filter(tagsAll = mapOf("p" to listOf(pTag1, pTag2, pTag3)))) + db.assertQuery(null, Filter(tagsAll = mapOf("p" to listOf(pTag1, id)))) + db.assertQuery(null, Filter(tagsAll = mapOf("p" to listOf(id)))) + } @Test - fun matchDualAllTags() { - db.insert(note) + fun matchDualAllTags() = + forEachDB { db -> + db.insert(note) - db.assertQuery(note, Filter(tagsAll = mapOf("p" to listOf(pTag1), "e" to listOf(rootETag)))) - db.assertQuery(note, Filter(tagsAll = mapOf("p" to listOf(pTag1, pTag2, pTag3), "e" to listOf(rootETag, replyETag)))) - db.assertQuery(null, Filter(tagsAll = mapOf("p" to listOf(pTag1, id), "e" to listOf(rootETag, replyETag)))) - db.assertQuery(null, Filter(tagsAll = mapOf("p" to listOf(pTag1, id), "e" to listOf(rootETag, pubkey)))) - db.assertQuery(null, Filter(tagsAll = mapOf("p" to listOf(pTag1, id), "e" to listOf(id, pubkey)))) - db.assertQuery(null, Filter(tagsAll = mapOf("p" to listOf(id), "e" to listOf(rootETag)))) - } + db.assertQuery(note, Filter(tagsAll = mapOf("p" to listOf(pTag1), "e" to listOf(rootETag)))) + db.assertQuery(note, Filter(tagsAll = mapOf("p" to listOf(pTag1, pTag2, pTag3), "e" to listOf(rootETag, replyETag)))) + db.assertQuery(null, Filter(tagsAll = mapOf("p" to listOf(pTag1, id), "e" to listOf(rootETag, replyETag)))) + db.assertQuery(null, Filter(tagsAll = mapOf("p" to listOf(pTag1, id), "e" to listOf(rootETag, pubkey)))) + db.assertQuery(null, Filter(tagsAll = mapOf("p" to listOf(pTag1, id), "e" to listOf(id, pubkey)))) + db.assertQuery(null, Filter(tagsAll = mapOf("p" to listOf(id), "e" to listOf(rootETag)))) + } @Test - fun matchKinds() { - db.insert(note) + fun matchKinds() = + forEachDB { db -> + db.insert(note) - db.assertQuery(note, Filter(kinds = listOf(kind))) - db.assertQuery(note, Filter(kinds = listOf(kind, 1221))) - db.assertQuery(null, Filter(kinds = listOf(1221))) - } + db.assertQuery(note, Filter(kinds = listOf(kind))) + db.assertQuery(note, Filter(kinds = listOf(kind, 1221))) + db.assertQuery(null, Filter(kinds = listOf(1221))) + } @Test - fun matchSince() { - db.insert(note) + fun matchSince() = + forEachDB { db -> + db.insert(note) - db.assertQuery(note, Filter(since = createdAt)) - db.assertQuery(note, Filter(since = createdAt - 1)) - db.assertQuery(null, Filter(since = createdAt + 1)) - } + db.assertQuery(note, Filter(since = createdAt)) + db.assertQuery(note, Filter(since = createdAt - 1)) + db.assertQuery(null, Filter(since = createdAt + 1)) + } @Test - fun matchUntil() { - db.insert(note) + fun matchUntil() = + forEachDB { db -> + db.insert(note) - db.assertQuery(note, Filter(until = createdAt)) - db.assertQuery(note, Filter(until = createdAt + 1)) - db.assertQuery(null, Filter(until = createdAt - 1)) - } + db.assertQuery(note, Filter(until = createdAt)) + db.assertQuery(note, Filter(until = createdAt + 1)) + db.assertQuery(null, Filter(until = createdAt - 1)) + } } diff --git a/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/LargeDBTests.kt b/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/LargeDBTests.kt index a16e2909b..a62de74ee 100644 --- a/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/LargeDBTests.kt +++ b/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/LargeDBTests.kt @@ -31,6 +31,7 @@ import com.vitorpamplona.quartz.nip40Expiration.isExpired import com.vitorpamplona.quartz.utils.Log import org.junit.After import org.junit.Before +import org.junit.Ignore import org.junit.Test import org.junit.runner.RunWith import java.util.zip.GZIPInputStream @@ -82,6 +83,7 @@ class LargeDBTests { } @Test + @Ignore("Not testing") fun insertDatabase() { events.forEach { event -> try { diff --git a/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryAssemblerTest.kt b/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryAssemblerTest.kt index 05f30020c..52d4c5423 100644 --- a/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryAssemblerTest.kt +++ b/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryAssemblerTest.kt @@ -26,6 +26,7 @@ import com.vitorpamplona.quartz.experimental.relationshipStatus.ContactCardEvent import com.vitorpamplona.quartz.nip01Core.metadata.MetadataEvent import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter import com.vitorpamplona.quartz.nip02FollowList.ContactListEvent +import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent import com.vitorpamplona.quartz.nip37Drafts.DraftWrapEvent import com.vitorpamplona.quartz.nip50Search.SearchRelayListEvent import com.vitorpamplona.quartz.nip65RelayList.AdvertisedRelayListEvent @@ -38,59 +39,68 @@ import org.junit.Test class QueryAssemblerTest { val hasher = TagNameValueHasher(0) - val builder = QueryBuilder(FullTextSearchModule(), { hasher }) - val key1 = "7c5eb72a4584fdaaeaa145b25c92ea9917704224951219dbd43acef9e91fb88d" val key2 = "f3ac434d61bc0f491a814782ccfdf9c439dae1f0bde9097ad4a245f4c495cd14" val key3 = "12ae0fd81c85e1e7d9ed096397dc3129849425fe6f8afce7213ebf38ddfc6ca9" - private lateinit var db: EventStore + private lateinit var dbAllIndexes: EventStore + private lateinit var dbNoKindIndexes: EventStore @Before fun setup() { val context = ApplicationProvider.getApplicationContext() - db = EventStore(context, null) + dbAllIndexes = EventStore(context, null, indexStrategy = DefaultIndexingStrategy(true)) + dbNoKindIndexes = EventStore(context, null, indexStrategy = DefaultIndexingStrategy(false)) } @After fun tearDown() { - db.close() + dbAllIndexes.close() + dbNoKindIndexes.close() } - fun explain(f: Filter) = builder.planQuery(f, hasher, db.store.readableDatabase) + fun EventStore.explain(f: Filter) = store.queryBuilder.planQuery(f, hasher, store.readableDatabase) - fun explain(f: List) = builder.planQuery(f, hasher, db.store.readableDatabase) + fun EventStore.explain(f: List) = store.queryBuilder.planQuery(f, hasher, store.readableDatabase) @Test fun testEmpty() { Assert.assertEquals( """ - SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers ORDER BY created_at DESC, id + SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers + ORDER BY created_at DESC └── SCAN event_headers USING INDEX query_by_created_at_id """.trimIndent(), - explain(Filter()), + dbAllIndexes.explain(Filter()), + ) + + Assert.assertEquals( + """ + SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers + ORDER BY created_at DESC + └── SCAN event_headers USING INDEX query_by_created_at_id + """.trimIndent(), + dbNoKindIndexes.explain(Filter()), ) } @Test fun testCheckDeletionEventExists() { - val query = - explain( - Filter( - kinds = listOf(5), - authors = listOf(key1), - tags = mapOf("e" to listOf(key2)), - since = 1750889190, - ), + val filter = + Filter( + kinds = listOf(5), + authors = listOf(key1), + tags = mapOf("e" to listOf(key2)), + since = 1750889190, ) TestCase.assertEquals( """ SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers INNER JOIN ( - SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags WHERE (event_tags.tag_hash = "2657743813502222172") AND (event_tags.kind = "5") AND (event_tags.pubkey_hash = "1730514094536529999") AND (event_tags.created_at >= "1750889190") + SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags WHERE (event_tags.tag_hash = "2657743813502222172") AND (event_tags.kind = "5") AND (event_tags.pubkey_hash = "1730514094536529999") AND (event_tags.created_at >= "1750889190") ) AS filtered ON event_headers.row_id = filtered.row_id - ORDER BY created_at DESC, id + ORDER BY created_at DESC ├── CO-ROUTINE filtered │ ├── SEARCH event_tags USING INDEX query_by_tags_hash_kind_pubkey (tag_hash=? AND kind=? AND pubkey_hash=? AND created_at>?) │ └── USE TEMP B-TREE FOR DISTINCT @@ -98,44 +108,55 @@ class QueryAssemblerTest { ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) └── USE TEMP B-TREE FOR ORDER BY """.trimIndent(), - query, + dbAllIndexes.explain(filter), + ) + + TestCase.assertEquals( + """ + SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers + INNER JOIN ( + SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags WHERE (event_tags.tag_hash = "2657743813502222172") AND (event_tags.kind = "5") AND (event_tags.pubkey_hash = "1730514094536529999") AND (event_tags.created_at >= "1750889190") + ) AS filtered + ON event_headers.row_id = filtered.row_id + ORDER BY created_at DESC + ├── CO-ROUTINE filtered + │ ├── SEARCH event_tags USING INDEX query_by_tags_hash_kind_pubkey (tag_hash=? AND kind=? AND pubkey_hash=? AND created_at>?) + │ └── USE TEMP B-TREE FOR DISTINCT + ├── SCAN filtered + ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) + └── USE TEMP B-TREE FOR ORDER BY + """.trimIndent(), + dbNoKindIndexes.explain(filter), ) } @Test fun testLimit() { - val explainer = explain(Filter(limit = 10)) + val filter = Filter(limit = 10) TestCase.assertEquals( """ SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers - INNER JOIN ( - SELECT event_headers.row_id as row_id FROM event_headers WHERE 1 = 1 ORDER BY event_headers.created_at DESC, event_headers.id ASC LIMIT 10 - ) AS filtered - ON event_headers.row_id = filtered.row_id - ORDER BY created_at DESC, id - ├── CO-ROUTINE filtered - │ └── SCAN event_headers USING COVERING INDEX query_by_created_at_id - ├── SCAN filtered - ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) - └── USE TEMP B-TREE FOR ORDER BY + ORDER BY created_at DESC + LIMIT 10 + └── SCAN event_headers USING INDEX query_by_created_at_id """.trimIndent(), - explainer, + dbAllIndexes.explain(filter), ) } @Test fun testLimits() { - val explainer = explain(listOf(Filter(limit = 10), Filter(limit = 30))) + val filter = listOf(Filter(limit = 10), Filter(limit = 30)) TestCase.assertEquals( """ SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers INNER JOIN ( - SELECT row_id FROM (SELECT event_headers.row_id as row_id FROM event_headers WHERE 1 = 1 ORDER BY event_headers.created_at DESC, event_headers.id ASC LIMIT 10) + SELECT row_id FROM (SELECT event_headers.row_id as row_id FROM event_headers ORDER BY event_headers.created_at DESC LIMIT 10) UNION - SELECT row_id FROM (SELECT event_headers.row_id as row_id FROM event_headers WHERE 1 = 1 ORDER BY event_headers.created_at DESC, event_headers.id ASC LIMIT 30) + SELECT row_id FROM (SELECT event_headers.row_id as row_id FROM event_headers ORDER BY event_headers.created_at DESC LIMIT 30) ) AS filtered ON event_headers.row_id = filtered.row_id - ORDER BY created_at DESC, id + ORDER BY created_at DESC ├── CO-ROUTINE filtered │ └── COMPOUND QUERY │ ├── LEFT-MOST SUBQUERY @@ -150,37 +171,35 @@ class QueryAssemblerTest { ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) └── USE TEMP B-TREE FOR ORDER BY """.trimIndent(), - explainer, + dbAllIndexes.explain(filter), ) } @Test fun testAllFeatures() { - val sql = - explain( - listOf( - Filter(limit = 10), - Filter( - authors = listOf(key1), - kinds = listOf(1, 1111), - search = "keywords", - limit = 100, - ), - Filter(kinds = listOf(20), search = "cats", limit = 30), + val filter = + listOf( + Filter(limit = 10), + Filter( + authors = listOf(key1), + kinds = listOf(1, 1111), + search = "keywords", + limit = 100, ), + Filter(kinds = listOf(20), search = "cats", limit = 30), ) TestCase.assertEquals( """ SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers INNER JOIN ( - SELECT row_id FROM (SELECT event_headers.row_id as row_id FROM event_headers WHERE 1 = 1 ORDER BY event_headers.created_at DESC, event_headers.id ASC LIMIT 10) + SELECT row_id FROM (SELECT event_headers.row_id as row_id FROM event_headers ORDER BY event_headers.created_at DESC LIMIT 10) UNION - SELECT row_id FROM (SELECT event_fts.event_header_row_id as row_id FROM event_fts INNER JOIN event_headers ON event_headers.row_id = event_fts.event_header_row_id WHERE (event_headers.kind IN ("1", "1111")) AND (event_headers.pubkey = "7c5eb72a4584fdaaeaa145b25c92ea9917704224951219dbd43acef9e91fb88d") AND (event_fts MATCH "keywords") ORDER BY event_headers.created_at DESC, event_headers.id ASC LIMIT 100) + SELECT row_id FROM (SELECT event_fts.event_header_row_id as row_id FROM event_fts INNER JOIN event_headers ON event_headers.row_id = event_fts.event_header_row_id WHERE (event_headers.kind IN ("1", "1111")) AND (event_headers.pubkey = "7c5eb72a4584fdaaeaa145b25c92ea9917704224951219dbd43acef9e91fb88d") AND (event_fts MATCH "keywords") ORDER BY event_headers.created_at DESC LIMIT 100) UNION - SELECT row_id FROM (SELECT event_fts.event_header_row_id as row_id FROM event_fts INNER JOIN event_headers ON event_headers.row_id = event_fts.event_header_row_id WHERE (event_headers.kind = "20") AND (event_fts MATCH "cats") ORDER BY event_headers.created_at DESC, event_headers.id ASC LIMIT 30) + SELECT row_id FROM (SELECT event_fts.event_header_row_id as row_id FROM event_fts INNER JOIN event_headers ON event_headers.row_id = event_fts.event_header_row_id WHERE (event_headers.kind = "20") AND (event_fts MATCH "cats") ORDER BY event_headers.created_at DESC LIMIT 30) ) AS filtered ON event_headers.row_id = filtered.row_id - ORDER BY created_at DESC, id + ORDER BY created_at DESC ├── CO-ROUTINE filtered │ └── COMPOUND QUERY │ ├── LEFT-MOST SUBQUERY @@ -195,99 +214,119 @@ class QueryAssemblerTest { │ │ └── SCAN (subquery-3) │ └── UNION USING TEMP B-TREE │ ├── CO-ROUTINE (subquery-5) - │ │ ├── SCAN event_fts VIRTUAL TABLE INDEX 4: - │ │ ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) - │ │ └── USE TEMP B-TREE FOR ORDER BY + │ │ ├── SEARCH event_headers USING COVERING INDEX query_by_kind_created (kind=?) + │ │ └── SCAN event_fts VIRTUAL TABLE INDEX 4: │ └── SCAN (subquery-5) ├── SCAN filtered ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) └── USE TEMP B-TREE FOR ORDER BY """.trimIndent(), - sql, + dbAllIndexes.explain(filter), ) } @Test - fun testKind() { - val sql = - explain( - listOf( - Filter( - kinds = listOf(ContactListEvent.KIND), - limit = 30, - ), + fun testSingleFilterConversionToSimpleQuery() { + val filter = + listOf( + Filter( + kinds = listOf(ContactListEvent.KIND), + limit = 30, + ), + ) + TestCase.assertEquals( + """ + SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers + WHERE kind = "3" + ORDER BY created_at DESC + LIMIT 30 + └── SEARCH event_headers USING INDEX query_by_kind_created (kind=?) + """.trimIndent(), + dbAllIndexes.explain(filter), + ) + } + + @Test + fun testKinds() { + val filter = + listOf( + Filter( + kinds = listOf(ContactListEvent.KIND), + limit = 30, + ), + Filter( + kinds = listOf(TextNoteEvent.KIND), + limit = 30, ), ) TestCase.assertEquals( """ SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers INNER JOIN ( - SELECT event_headers.row_id as row_id FROM event_headers WHERE event_headers.kind = "3" ORDER BY event_headers.created_at DESC, event_headers.id ASC LIMIT 30 + SELECT row_id FROM (SELECT event_headers.row_id as row_id FROM event_headers WHERE event_headers.kind = "3" ORDER BY event_headers.created_at DESC LIMIT 30) + UNION + SELECT row_id FROM (SELECT event_headers.row_id as row_id FROM event_headers WHERE event_headers.kind = "1" ORDER BY event_headers.created_at DESC LIMIT 30) ) AS filtered ON event_headers.row_id = filtered.row_id - ORDER BY created_at DESC, id + ORDER BY created_at DESC ├── CO-ROUTINE filtered - │ ├── SEARCH event_headers USING INDEX query_by_kind_pubkey_created (kind=?) - │ └── USE TEMP B-TREE FOR ORDER BY + │ └── COMPOUND QUERY + │ ├── LEFT-MOST SUBQUERY + │ │ ├── CO-ROUTINE (subquery-1) + │ │ │ └── SEARCH event_headers USING COVERING INDEX query_by_kind_created (kind=?) + │ │ └── SCAN (subquery-1) + │ └── UNION USING TEMP B-TREE + │ ├── CO-ROUTINE (subquery-3) + │ │ └── SEARCH event_headers USING COVERING INDEX query_by_kind_created (kind=?) + │ └── SCAN (subquery-3) ├── SCAN filtered ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) └── USE TEMP B-TREE FOR ORDER BY """.trimIndent(), - sql, + dbAllIndexes.explain(filter), ) } @Test fun testKindAndDTag() { - val sql = - explain( - listOf( - Filter( - kinds = listOf(ContactListEvent.KIND), - tags = mapOf("d" to listOf("")), - limit = 30, - ), + val filter = + listOf( + Filter( + kinds = listOf(ContactListEvent.KIND), + tags = mapOf("d" to listOf("")), + limit = 30, ), ) TestCase.assertEquals( """ SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers - INNER JOIN ( - SELECT event_headers.row_id as row_id FROM event_headers WHERE (event_headers.kind = "3") AND (event_headers.d_tag = "") ORDER BY event_headers.created_at DESC, event_headers.id ASC LIMIT 30 - ) AS filtered - ON event_headers.row_id = filtered.row_id - ORDER BY created_at DESC, id - ├── CO-ROUTINE filtered - │ ├── SEARCH event_headers USING INDEX query_by_kind_pubkey_created (kind=?) - │ └── USE TEMP B-TREE FOR ORDER BY - ├── SCAN filtered - ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) - └── USE TEMP B-TREE FOR ORDER BY + WHERE (kind = "3") AND (d_tag = "") + ORDER BY created_at DESC + LIMIT 30 + └── SEARCH event_headers USING INDEX query_by_kind_created (kind=?) """.trimIndent(), - sql, + dbAllIndexes.explain(filter), ) } @Test fun testFollowersOf() { - val sql = - explain( - listOf( - Filter( - kinds = listOf(ContactListEvent.KIND), - tags = mapOf("p" to listOf("460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c")), - limit = 30, - ), + val filter = + listOf( + Filter( + kinds = listOf(ContactListEvent.KIND), + tags = mapOf("p" to listOf("460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c")), + limit = 30, ), ) TestCase.assertEquals( """ SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers INNER JOIN ( - SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags WHERE (event_tags.tag_hash = "-4551135004136952885") AND (event_tags.kind = "3") ORDER BY event_tags.created_at DESC LIMIT 30 + SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags WHERE (event_tags.tag_hash = "-4551135004136952885") AND (event_tags.kind = "3") ORDER BY event_tags.created_at DESC LIMIT 30 ) AS filtered ON event_headers.row_id = filtered.row_id - ORDER BY created_at DESC, id + ORDER BY created_at DESC ├── CO-ROUTINE filtered │ ├── SEARCH event_tags USING INDEX query_by_tags_hash_kind (tag_hash=? AND kind=?) │ └── USE TEMP B-TREE FOR DISTINCT @@ -295,29 +334,27 @@ class QueryAssemblerTest { ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) └── USE TEMP B-TREE FOR ORDER BY """.trimIndent(), - sql, + dbAllIndexes.explain(filter), ) } @Test fun testNotificationsOf() { - val sql = - explain( - listOf( - Filter( - tags = mapOf("p" to listOf("460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c")), - limit = 30, - ), + val filter = + listOf( + Filter( + tags = mapOf("p" to listOf("460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c")), + limit = 30, ), ) TestCase.assertEquals( """ SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers INNER JOIN ( - SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags WHERE event_tags.tag_hash = "-4551135004136952885" ORDER BY event_tags.created_at DESC LIMIT 30 + SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags WHERE event_tags.tag_hash = "-4551135004136952885" ORDER BY event_tags.created_at DESC LIMIT 30 ) AS filtered ON event_headers.row_id = filtered.row_id - ORDER BY created_at DESC, id + ORDER BY created_at DESC ├── CO-ROUTINE filtered │ ├── SEARCH event_tags USING INDEX query_by_tags_hash (tag_hash=?) │ └── USE TEMP B-TREE FOR DISTINCT @@ -325,30 +362,28 @@ class QueryAssemblerTest { ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) └── USE TEMP B-TREE FOR ORDER BY """.trimIndent(), - sql, + dbAllIndexes.explain(filter), ) } @Test fun testTagsAndKinds() { - val sql = - explain( - listOf( - Filter( - kinds = listOf(ContactListEvent.KIND), - tags = mapOf("p" to listOf("460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c")), - limit = 30, - ), + val filter = + listOf( + Filter( + kinds = listOf(ContactListEvent.KIND), + tags = mapOf("p" to listOf("460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c")), + limit = 30, ), ) TestCase.assertEquals( """ SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers INNER JOIN ( - SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags WHERE (event_tags.tag_hash = "-4551135004136952885") AND (event_tags.kind = "3") ORDER BY event_tags.created_at DESC LIMIT 30 + SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags WHERE (event_tags.tag_hash = "-4551135004136952885") AND (event_tags.kind = "3") ORDER BY event_tags.created_at DESC LIMIT 30 ) AS filtered ON event_headers.row_id = filtered.row_id - ORDER BY created_at DESC, id + ORDER BY created_at DESC ├── CO-ROUTINE filtered │ ├── SEARCH event_tags USING INDEX query_by_tags_hash_kind (tag_hash=? AND kind=?) │ └── USE TEMP B-TREE FOR DISTINCT @@ -356,30 +391,28 @@ class QueryAssemblerTest { ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) └── USE TEMP B-TREE FOR ORDER BY """.trimIndent(), - sql, + dbAllIndexes.explain(filter), ) } @Test fun testTagsAndAuthors() { - val sql = - explain( - listOf( - Filter( - authors = listOf(key1), - tags = mapOf("p" to listOf("460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c")), - limit = 30, - ), + val filter = + listOf( + Filter( + authors = listOf(key1), + tags = mapOf("p" to listOf("460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c")), + limit = 30, ), ) TestCase.assertEquals( """ SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers INNER JOIN ( - SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags WHERE (event_tags.tag_hash = "-4551135004136952885") AND (event_tags.pubkey_hash = "1730514094536529999") ORDER BY event_tags.created_at DESC LIMIT 30 + SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags WHERE (event_tags.tag_hash = "-4551135004136952885") AND (event_tags.pubkey_hash = "1730514094536529999") ORDER BY event_tags.created_at DESC LIMIT 30 ) AS filtered ON event_headers.row_id = filtered.row_id - ORDER BY created_at DESC, id + ORDER BY created_at DESC ├── CO-ROUTINE filtered │ ├── SEARCH event_tags USING INDEX query_by_tags_hash (tag_hash=?) │ └── USE TEMP B-TREE FOR DISTINCT @@ -387,34 +420,32 @@ class QueryAssemblerTest { ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) └── USE TEMP B-TREE FOR ORDER BY """.trimIndent(), - sql, + dbAllIndexes.explain(filter), ) } @Test fun testTwoTags() { - val sql = - explain( - listOf( - Filter( - kinds = listOf(1), - tags = - mapOf( - "p" to listOf("460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c"), - "t" to listOf("hashtag"), - ), - limit = 30, - ), + val filter = + listOf( + Filter( + kinds = listOf(1), + tags = + mapOf( + "p" to listOf("460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c"), + "t" to listOf("hashtag"), + ), + limit = 30, ), ) TestCase.assertEquals( """ SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers INNER JOIN ( - SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags INNER JOIN event_tags as event_tagsIn1 ON event_tagsIn1.event_header_row_id = event_tags.event_header_row_id AND event_tagsIn1.created_at = event_tags.created_at WHERE (event_tags.tag_hash = "-4551135004136952885") AND (event_tagsIn1.tag_hash = "-6379614208644810021") AND (event_tags.kind = "1") ORDER BY event_tags.created_at DESC LIMIT 30 + SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags INNER JOIN event_tags as event_tagsIn1 ON event_tagsIn1.event_header_row_id = event_tags.event_header_row_id AND event_tagsIn1.created_at = event_tags.created_at WHERE (event_tags.tag_hash = "-4551135004136952885") AND (event_tagsIn1.tag_hash = "-6379614208644810021") AND (event_tags.kind = "1") ORDER BY event_tags.created_at DESC LIMIT 30 ) AS filtered ON event_headers.row_id = filtered.row_id - ORDER BY created_at DESC, id + ORDER BY created_at DESC ├── CO-ROUTINE filtered │ ├── SEARCH event_tags USING INDEX query_by_tags_hash_kind (tag_hash=? AND kind=?) │ ├── SEARCH event_tagsIn1 USING INDEX query_by_tags_hash (tag_hash=? AND created_at=?) @@ -423,101 +454,87 @@ class QueryAssemblerTest { ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) └── USE TEMP B-TREE FOR ORDER BY """.trimIndent(), - sql, + dbAllIndexes.explain(filter), ) } @Test fun testIdQuery() { - val sql = explain(Filter(ids = listOf(key1))) + val filter = Filter(ids = listOf(key1)) TestCase.assertEquals( """ SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers - INNER JOIN ( - SELECT event_headers.row_id as row_id FROM event_headers WHERE event_headers.id = "7c5eb72a4584fdaaeaa145b25c92ea9917704224951219dbd43acef9e91fb88d" - ) AS filtered - ON event_headers.row_id = filtered.row_id - ORDER BY created_at DESC, id - ├── SEARCH event_headers USING COVERING INDEX event_headers_id (id=?) - └── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) + WHERE id = "7c5eb72a4584fdaaeaa145b25c92ea9917704224951219dbd43acef9e91fb88d" + ORDER BY created_at DESC + └── SEARCH event_headers USING INDEX event_headers_id (id=?) """.trimIndent(), - sql, + dbAllIndexes.explain(filter), ) } @Test fun testAuthors() { - val sql = explain(Filter(authors = listOf(key1, key2), kinds = listOf(1, 30023), limit = 300)) + val filter = Filter(authors = listOf(key1, key2), kinds = listOf(1, 30023), limit = 300) TestCase.assertEquals( """ SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers - INNER JOIN ( - SELECT event_headers.row_id as row_id FROM event_headers WHERE (event_headers.kind IN ("1", "30023")) AND (event_headers.pubkey IN ("7c5eb72a4584fdaaeaa145b25c92ea9917704224951219dbd43acef9e91fb88d", "f3ac434d61bc0f491a814782ccfdf9c439dae1f0bde9097ad4a245f4c495cd14")) ORDER BY event_headers.created_at DESC, event_headers.id ASC LIMIT 300 - ) AS filtered - ON event_headers.row_id = filtered.row_id - ORDER BY created_at DESC, id - ├── CO-ROUTINE filtered - │ ├── SEARCH event_headers USING INDEX query_by_kind_pubkey_created (kind=? AND pubkey=?) - │ └── USE TEMP B-TREE FOR ORDER BY - ├── SCAN filtered - ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) + WHERE (kind IN ("1", "30023")) AND (pubkey IN ("7c5eb72a4584fdaaeaa145b25c92ea9917704224951219dbd43acef9e91fb88d", "f3ac434d61bc0f491a814782ccfdf9c439dae1f0bde9097ad4a245f4c495cd14")) + ORDER BY created_at DESC + LIMIT 300 + ├── SEARCH event_headers USING INDEX query_by_kind_pubkey_created (kind=? AND pubkey=?) └── USE TEMP B-TREE FOR ORDER BY """.trimIndent(), - sql, + dbAllIndexes.explain(filter), ) } @Test fun testAuthorsAndSearch() { - val sql = explain(Filter(authors = listOf(key1, key2, key3), search = "keywords")) + val filter = Filter(authors = listOf(key1, key2, key3), search = "keywords") + println(dbAllIndexes.explain(filter)) TestCase.assertEquals( """ - SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers - INNER JOIN ( - SELECT event_fts.event_header_row_id as row_id FROM event_fts INNER JOIN event_headers ON event_headers.row_id = event_fts.event_header_row_id WHERE (event_headers.pubkey IN ("7c5eb72a4584fdaaeaa145b25c92ea9917704224951219dbd43acef9e91fb88d", "f3ac434d61bc0f491a814782ccfdf9c439dae1f0bde9097ad4a245f4c495cd14", "12ae0fd81c85e1e7d9ed096397dc3129849425fe6f8afce7213ebf38ddfc6ca9")) AND (event_fts MATCH "keywords") - ) AS filtered - ON event_headers.row_id = filtered.row_id - ORDER BY created_at DESC, id + SELECT event_headers.id, event_headers.pubkey, event_headers.created_at, event_headers.kind, event_headers.tags, event_headers.content, event_headers.sig FROM event_headers + INNER JOIN event_fts ON event_headers.row_id = event_fts.event_header_row_id + WHERE (event_fts MATCH "keywords") AND (event_headers.pubkey IN ("7c5eb72a4584fdaaeaa145b25c92ea9917704224951219dbd43acef9e91fb88d", "f3ac434d61bc0f491a814782ccfdf9c439dae1f0bde9097ad4a245f4c495cd14", "12ae0fd81c85e1e7d9ed096397dc3129849425fe6f8afce7213ebf38ddfc6ca9")) + ORDER BY event_headers.created_at DESC ├── SCAN event_fts VIRTUAL TABLE INDEX 4: ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) - ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) └── USE TEMP B-TREE FOR ORDER BY """.trimIndent(), - sql, + dbAllIndexes.explain(filter), ) } @Test fun testKindAndSearch() { - val sql = explain(Filter(kinds = listOf(1, 1111, 10000), search = "keywords")) + val filter = Filter(kinds = listOf(1, 1111, 10000), search = "keywords") + println(dbAllIndexes.explain(filter)) TestCase.assertEquals( """ - SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers - INNER JOIN ( - SELECT event_fts.event_header_row_id as row_id FROM event_fts INNER JOIN event_headers ON event_headers.row_id = event_fts.event_header_row_id WHERE (event_headers.kind IN ("1", "1111", "10000")) AND (event_fts MATCH "keywords") - ) AS filtered - ON event_headers.row_id = filtered.row_id - ORDER BY created_at DESC, id + SELECT event_headers.id, event_headers.pubkey, event_headers.created_at, event_headers.kind, event_headers.tags, event_headers.content, event_headers.sig FROM event_headers + INNER JOIN event_fts ON event_headers.row_id = event_fts.event_header_row_id + WHERE (event_fts MATCH "keywords") AND (event_headers.kind IN ("1", "1111", "10000")) + ORDER BY event_headers.created_at DESC ├── SCAN event_fts VIRTUAL TABLE INDEX 4: ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) - ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) └── USE TEMP B-TREE FOR ORDER BY """.trimIndent(), - sql, + dbAllIndexes.explain(filter), ) } @Test fun testAllTag() { - val sql = explain(Filter(tagsAll = mapOf("p" to listOf(key1, key2)))) + val filter = Filter(tagsAll = mapOf("p" to listOf(key1, key2))) TestCase.assertEquals( """ SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers INNER JOIN ( - SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags INNER JOIN event_tags as event_tagsAll0_1 ON event_tagsAll0_1.event_header_row_id = event_tags.event_header_row_id AND event_tagsAll0_1.created_at = event_tags.created_at WHERE (event_tags.tag_hash = "884286737453847614") AND (event_tagsAll0_1.tag_hash = "-4988851810256311323") + SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags INNER JOIN event_tags as event_tagsAll0_1 ON event_tagsAll0_1.event_header_row_id = event_tags.event_header_row_id AND event_tagsAll0_1.created_at = event_tags.created_at WHERE (event_tags.tag_hash = "884286737453847614") AND (event_tagsAll0_1.tag_hash = "-4988851810256311323") ) AS filtered ON event_headers.row_id = filtered.row_id - ORDER BY created_at DESC, id + ORDER BY created_at DESC ├── CO-ROUTINE filtered │ ├── SEARCH event_tags USING INDEX query_by_tags_hash_kind (tag_hash=?) │ ├── SEARCH event_tagsAll0_1 USING INDEX query_by_tags_hash (tag_hash=? AND created_at=?) @@ -526,32 +543,30 @@ class QueryAssemblerTest { ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) └── USE TEMP B-TREE FOR ORDER BY """.trimIndent(), - sql, + dbAllIndexes.explain(filter), ) } @Test fun testReportLikeFilter() { - val sql = - explain( - Filter( - kinds = listOf(ContactListEvent.KIND), - authors = listOf("460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c"), - tags = - mapOf( - "p" to listOf("460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c"), - ), - limit = 500, - ), + val filter = + Filter( + kinds = listOf(ContactListEvent.KIND), + authors = listOf("460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c"), + tags = + mapOf( + "p" to listOf("460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c"), + ), + limit = 500, ) assertEquals( """ SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers INNER JOIN ( - SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags WHERE (event_tags.tag_hash = "-4551135004136952885") AND (event_tags.kind = "3") AND (event_tags.pubkey_hash = "5446767199141196776") ORDER BY event_tags.created_at DESC LIMIT 500 + SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags WHERE (event_tags.tag_hash = "-4551135004136952885") AND (event_tags.kind = "3") AND (event_tags.pubkey_hash = "5446767199141196776") ORDER BY event_tags.created_at DESC LIMIT 500 ) AS filtered ON event_headers.row_id = filtered.row_id - ORDER BY created_at DESC, id + ORDER BY created_at DESC ├── CO-ROUTINE filtered │ ├── SEARCH event_tags USING INDEX query_by_tags_hash_kind_pubkey (tag_hash=? AND kind=? AND pubkey_hash=?) │ └── USE TEMP B-TREE FOR DISTINCT @@ -559,32 +574,29 @@ class QueryAssemblerTest { ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) └── USE TEMP B-TREE FOR ORDER BY """.trimIndent(), - sql, + dbAllIndexes.explain(filter), ) } @Test fun testFollowersSinceNov2025() { - val sql = - explain( - Filter( - kinds = listOf(ContactListEvent.KIND), - tags = - mapOf( - "p" to listOf("460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c"), - ), - since = 1764553447, // Nov 2025 - ), + val filter = + Filter( + kinds = listOf(ContactListEvent.KIND), + tags = + mapOf( + "p" to listOf("460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c"), + ), + since = 1764553447, // Nov 2025 ) - println(sql) assertEquals( """ SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers INNER JOIN ( - SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags WHERE (event_tags.tag_hash = "-4551135004136952885") AND (event_tags.kind = "3") AND (event_tags.created_at >= "1764553447") + SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags WHERE (event_tags.tag_hash = "-4551135004136952885") AND (event_tags.kind = "3") AND (event_tags.created_at >= "1764553447") ) AS filtered ON event_headers.row_id = filtered.row_id - ORDER BY created_at DESC, id + ORDER BY created_at DESC ├── CO-ROUTINE filtered │ ├── SEARCH event_tags USING INDEX query_by_tags_hash_kind (tag_hash=? AND kind=? AND created_at>?) │ └── USE TEMP B-TREE FOR DISTINCT @@ -592,119 +604,93 @@ class QueryAssemblerTest { ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) └── USE TEMP B-TREE FOR ORDER BY """.trimIndent(), - sql, + dbAllIndexes.explain(filter), ) } @Test fun testAllAddressablesOfAKindDownload() { - val sql = - explain( - Filter( - kinds = listOf(DraftWrapEvent.KIND), - authors = listOf("460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c"), - since = 1764553447, // Nov 2025 - ), + val filter = + Filter( + kinds = listOf(DraftWrapEvent.KIND), + authors = listOf("460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c"), + since = 1764553447, // Nov 2025 ) - println(sql) assertEquals( """ SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers - INNER JOIN ( - SELECT event_headers.row_id as row_id FROM event_headers WHERE (event_headers.kind = "31234") AND (event_headers.pubkey = "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c") AND (event_headers.created_at >= "1764553447") AND ((event_headers.kind >= 30000 AND event_headers.kind < 40000)) - ) AS filtered - ON event_headers.row_id = filtered.row_id - ORDER BY created_at DESC, id - ├── SEARCH event_headers USING COVERING INDEX query_by_kind_pubkey_created (kind=? AND pubkey=? AND created_at>?) - ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) - └── USE TEMP B-TREE FOR ORDER BY + WHERE (kind = "31234") AND (pubkey = "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c") AND (created_at >= "1764553447") + ORDER BY created_at DESC + └── SEARCH event_headers USING INDEX query_by_kind_pubkey_created (kind=? AND pubkey=? AND created_at>?) """.trimIndent(), - sql, + dbAllIndexes.explain(filter), ) } @Test fun testReplaceablesOfMultipleKindsDownloadByDateLimit() { - val sql = - explain( - Filter( - kinds = listOf(MetadataEvent.KIND, SearchRelayListEvent.KIND, AdvertisedRelayListEvent.KIND), - authors = listOf("460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c"), - limit = 20, - since = 1764553447, // Nov 2025 - ), + val filter = + Filter( + kinds = listOf(MetadataEvent.KIND, SearchRelayListEvent.KIND, AdvertisedRelayListEvent.KIND), + authors = listOf("460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c"), + limit = 20, + since = 1764553447, // Nov 2025 ) assertEquals( """ SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers - INNER JOIN ( - SELECT event_headers.row_id as row_id FROM event_headers WHERE (event_headers.kind IN ("0", "10007", "10002")) AND (event_headers.pubkey = "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c") AND (event_headers.created_at >= "1764553447") ORDER BY event_headers.created_at DESC, event_headers.id ASC LIMIT 20 - ) AS filtered - ON event_headers.row_id = filtered.row_id - ORDER BY created_at DESC, id - ├── CO-ROUTINE filtered - │ ├── SEARCH event_headers USING INDEX query_by_kind_pubkey_created (kind=? AND pubkey=? AND created_at>?) - │ └── USE TEMP B-TREE FOR ORDER BY - ├── SCAN filtered - ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) + WHERE (kind IN ("0", "10007", "10002")) AND (pubkey = "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c") AND (created_at >= "1764553447") + ORDER BY created_at DESC + LIMIT 20 + ├── SEARCH event_headers USING INDEX query_by_kind_pubkey_created (kind=? AND pubkey=? AND created_at>?) └── USE TEMP B-TREE FOR ORDER BY """.trimIndent(), - sql, + dbAllIndexes.explain(filter), ) } @Test fun testReplaceablesOfMultipleKindsDownload() { - val sql = - explain( - Filter( - kinds = listOf(MetadataEvent.KIND, SearchRelayListEvent.KIND, AdvertisedRelayListEvent.KIND), - authors = listOf("460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c"), - ), + val filter = + Filter( + kinds = listOf(MetadataEvent.KIND, SearchRelayListEvent.KIND, AdvertisedRelayListEvent.KIND), + authors = listOf("460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c"), ) + assertEquals( """ SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers - INNER JOIN ( - SELECT event_headers.row_id as row_id FROM event_headers WHERE (event_headers.kind IN ("0", "10007", "10002")) AND (event_headers.pubkey = "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c") - ) AS filtered - ON event_headers.row_id = filtered.row_id - ORDER BY created_at DESC, id - ├── SEARCH event_headers USING COVERING INDEX query_by_kind_pubkey_created (kind=? AND pubkey=?) - ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) + WHERE (kind IN ("0", "10007", "10002")) AND (pubkey = "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c") + ORDER BY created_at DESC + ├── SEARCH event_headers USING INDEX query_by_kind_pubkey_created (kind=? AND pubkey=?) └── USE TEMP B-TREE FOR ORDER BY """.trimIndent(), - sql, + dbAllIndexes.explain(filter), ) } @Test fun testContactCardDownloadFromTrustedKeys() { - val sql = - explain( - Filter( - kinds = listOf(ContactCardEvent.KIND), - authors = listOf("460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c"), - tags = - mapOf( - "d" to listOf("460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c"), - ), - since = 1764553447, // Nov 2025 - ), + val filter = + Filter( + kinds = listOf(ContactCardEvent.KIND), + authors = listOf("460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c"), + tags = + mapOf( + "d" to listOf("460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c"), + ), + since = 1764553447, // Nov 2025 ) + assertEquals( """ SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers - INNER JOIN ( - SELECT event_headers.row_id as row_id FROM event_headers WHERE (event_headers.kind = "30382") AND (event_headers.pubkey = "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c") AND (event_headers.d_tag = "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c") AND (event_headers.created_at >= "1764553447") AND ((event_headers.kind >= 30000 AND event_headers.kind < 40000)) - ) AS filtered - ON event_headers.row_id = filtered.row_id - ORDER BY created_at DESC, id + WHERE (kind = "30382") AND (pubkey = "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c") AND (d_tag = "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c") AND (created_at >= "1764553447") AND ((kind >= 30000 AND kind < 40000)) + ORDER BY created_at DESC ├── SEARCH event_headers USING INDEX addressable_idx (kind=? AND pubkey=? AND d_tag=?) - ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) └── USE TEMP B-TREE FOR ORDER BY """.trimIndent(), - sql, + dbAllIndexes.explain(filter), ) } } diff --git a/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/ReplaceableTest.kt b/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/ReplaceableTest.kt index 182414ef2..620b5301f 100644 --- a/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/ReplaceableTest.kt +++ b/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/ReplaceableTest.kt @@ -20,9 +20,7 @@ */ package com.vitorpamplona.quartz.nip01Core.store.sqlite -import android.content.Context import android.database.sqlite.SQLiteConstraintException -import androidx.test.core.app.ApplicationProvider import com.vitorpamplona.quartz.nip01Core.metadata.MetadataEvent import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerSync @@ -30,136 +28,125 @@ import com.vitorpamplona.quartz.utils.TimeUtils import junit.framework.TestCase import junit.framework.TestCase.assertEquals import junit.framework.TestCase.fail -import org.junit.After -import org.junit.Before import org.junit.Test -class ReplaceableTest { - private lateinit var db: EventStore - +class ReplaceableTest : BaseDBTest() { val signer = NostrSignerSync() - @Before - fun setup() { - val context = ApplicationProvider.getApplicationContext() - db = EventStore(context, null) - } - - @After - fun tearDown() { - db.close() - } - @Test - fun testReplacing() { - val time = TimeUtils.now() - val version1 = signer.sign(MetadataEvent.createNew("Vitor 1", createdAt = time)) - val version2 = signer.sign(MetadataEvent.createNew("Vitor 2", createdAt = time + 1)) - val version3 = signer.sign(MetadataEvent.createNew("Vitor 3", createdAt = time + 2)) + fun testReplacing() = + forEachDB { db -> + val time = TimeUtils.now() + val version1 = signer.sign(MetadataEvent.createNew("Vitor 1", createdAt = time)) + val version2 = signer.sign(MetadataEvent.createNew("Vitor 2", createdAt = time + 1)) + val version3 = signer.sign(MetadataEvent.createNew("Vitor 3", createdAt = time + 2)) - val addressableQuery = Filter(kinds = listOf(version1.kind), authors = listOf(version1.pubKey), tags = mapOf("d" to listOf(version1.dTag()))) + val addressableQuery = Filter(kinds = listOf(version1.kind), authors = listOf(version1.pubKey), tags = mapOf("d" to listOf(version1.dTag()))) - db.insert(version1) - - db.assertQuery(version1, Filter(ids = listOf(version1.id))) - db.assertQuery(version1, addressableQuery) - - db.insert(version2) - - db.assertQuery(null, Filter(ids = listOf(version1.id))) - db.assertQuery(version2, Filter(ids = listOf(version2.id))) - db.assertQuery(version2, addressableQuery) - - db.insert(version3) - - db.assertQuery(null, Filter(ids = listOf(version1.id))) - db.assertQuery(null, Filter(ids = listOf(version2.id))) - db.assertQuery(version3, Filter(ids = listOf(version3.id))) - db.assertQuery(version3, addressableQuery) - } - - @Test - fun testBlockingOldVersions() { - val time = TimeUtils.now() - val version1 = signer.sign(MetadataEvent.createNew("Vitor 1", createdAt = time)) - val version2 = signer.sign(MetadataEvent.createNew("Vitor 2", createdAt = time + 1)) - val version3 = signer.sign(MetadataEvent.createNew("Vitor 3", createdAt = time + 2)) - - val addressableQuery = Filter(kinds = listOf(version1.kind), authors = listOf(version1.pubKey), tags = mapOf("d" to listOf(version1.dTag()))) - - db.insert(version3) - - db.assertQuery(version3, Filter(ids = listOf(version3.id))) - - try { - db.insert(version2) - fail("It should not allow inserting an older version") - } catch (e: Exception) { - TestCase.assertTrue(e is SQLiteConstraintException) - } - - try { db.insert(version1) - fail("It should not allow inserting an older version") - } catch (e: Exception) { - TestCase.assertTrue(e is SQLiteConstraintException) + + db.assertQuery(version1, Filter(ids = listOf(version1.id))) + db.assertQuery(version1, addressableQuery) + + db.insert(version2) + + db.assertQuery(null, Filter(ids = listOf(version1.id))) + db.assertQuery(version2, Filter(ids = listOf(version2.id))) + db.assertQuery(version2, addressableQuery) + + db.insert(version3) + + db.assertQuery(null, Filter(ids = listOf(version1.id))) + db.assertQuery(null, Filter(ids = listOf(version2.id))) + db.assertQuery(version3, Filter(ids = listOf(version3.id))) + db.assertQuery(version3, addressableQuery) } - db.assertQuery(version3, Filter(ids = listOf(version3.id))) - db.assertQuery(version3, addressableQuery) - db.assertQuery(null, Filter(ids = listOf(version2.id))) - db.assertQuery(null, Filter(ids = listOf(version1.id))) - } + @Test + fun testBlockingOldVersions() = + forEachDB { db -> + val time = TimeUtils.now() + val version1 = signer.sign(MetadataEvent.createNew("Vitor 1", createdAt = time)) + val version2 = signer.sign(MetadataEvent.createNew("Vitor 2", createdAt = time + 1)) + val version3 = signer.sign(MetadataEvent.createNew("Vitor 3", createdAt = time + 2)) + + val addressableQuery = Filter(kinds = listOf(version1.kind), authors = listOf(version1.pubKey), tags = mapOf("d" to listOf(version1.dTag()))) + + db.insert(version3) + + db.assertQuery(version3, Filter(ids = listOf(version3.id))) + + try { + db.insert(version2) + fail("It should not allow inserting an older version") + } catch (e: Exception) { + TestCase.assertTrue(e is SQLiteConstraintException) + } + + try { + db.insert(version1) + fail("It should not allow inserting an older version") + } catch (e: Exception) { + TestCase.assertTrue(e is SQLiteConstraintException) + } + + db.assertQuery(version3, Filter(ids = listOf(version3.id))) + db.assertQuery(version3, addressableQuery) + db.assertQuery(null, Filter(ids = listOf(version2.id))) + db.assertQuery(null, Filter(ids = listOf(version1.id))) + } @Test - fun testTriggersIndexUsageKind0() { - val sql = - """ - SELECT * FROM event_headers - WHERE - event_headers.kind = 0 AND - event_headers.pubkey = 'aa' AND - event_headers.created_at < 1766686500 - """.trimIndent() + fun testTriggersIndexUsageKind0() = + forEachDB { db -> + val sql = + """ + SELECT * FROM event_headers + WHERE + event_headers.kind = 0 AND + event_headers.pubkey = 'aa' AND + event_headers.created_at < 1766686500 + """.trimIndent() - val explainer = db.store.explainQuery(sql) + val explainer = db.store.explainQuery(sql) - assertEquals( - """ - SELECT * FROM event_headers - WHERE - event_headers.kind = 0 AND - event_headers.pubkey = 'aa' AND - event_headers.created_at < 1766686500 - └── SEARCH event_headers USING INDEX query_by_kind_pubkey_created (kind=? AND pubkey=? AND created_at + val sql = + """ + SELECT * FROM event_headers + WHERE + event_headers.kind = 3 AND + event_headers.pubkey = 'aa' AND + event_headers.created_at < 1766686500 + """.trimIndent() - val explainer = db.store.explainQuery(sql) + val explainer = db.store.explainQuery(sql) - assertEquals( - """ - SELECT * FROM event_headers - WHERE - event_headers.kind = 3 AND - event_headers.pubkey = 'aa' AND - event_headers.created_at < 1766686500 - └── SEARCH event_headers USING INDEX query_by_kind_pubkey_created (kind=? AND pubkey=? AND created_at() - db = EventStore(context, null, relayUrl = "testUrl") - } - - @After - fun tearDown() { - db.close() - } - @Test - fun testInsertDeleteEvent() { - val time = TimeUtils.now() - val note1 = signer.sign(TextNoteEvent.build("test1", createdAt = time)) - val note2 = signer.sign(TextNoteEvent.build("test2", createdAt = time + 1)) - val note3 = signer.sign(TextNoteEvent.build("test3", createdAt = time + 2)) + fun testInsertDeleteEvent() = + forEachDB { db -> + val time = TimeUtils.now() + val note1 = signer.sign(TextNoteEvent.build("test1", createdAt = time)) + val note2 = signer.sign(TextNoteEvent.build("test2", createdAt = time + 1)) + val note3 = signer.sign(TextNoteEvent.build("test3", createdAt = time + 2)) - db.insert(note1) - db.insert(note2) - db.insert(note3) - - db.assertQuery(note1, Filter(ids = listOf(note1.id))) - db.assertQuery(note2, Filter(ids = listOf(note2.id))) - db.assertQuery(note3, Filter(ids = listOf(note3.id))) - - val vanish = signer.sign(RequestToVanishEvent.build("testUrl", createdAt = time + 2)) - - db.insert(vanish) - - db.assertQuery(vanish, Filter(ids = listOf(vanish.id))) - db.assertQuery(null, Filter(ids = listOf(note1.id))) - db.assertQuery(null, Filter(ids = listOf(note2.id))) - db.assertQuery(note3, Filter(ids = listOf(note3.id))) - - // trying to insert again should fail. - try { db.insert(note1) - fail("Should not be able to insert a deleted event") - } catch (e: SQLiteConstraintException) { - assertEquals("blocked: a request to vanish event exists (code 1811 SQLITE_CONSTRAINT_TRIGGER)", e.message) - } + db.insert(note2) + db.insert(note3) - db.assertQuery(vanish, Filter(ids = listOf(vanish.id))) - db.assertQuery(null, Filter(ids = listOf(note1.id))) - db.assertQuery(null, Filter(ids = listOf(note2.id))) - db.assertQuery(note3, Filter(ids = listOf(note3.id))) - } + db.assertQuery(note1, Filter(ids = listOf(note1.id))) + db.assertQuery(note2, Filter(ids = listOf(note2.id))) + db.assertQuery(note3, Filter(ids = listOf(note3.id))) + + val vanish = signer.sign(RequestToVanishEvent.build("wss://quartz.local", createdAt = time + 2)) + + db.insert(vanish) + + db.assertQuery(vanish, Filter(ids = listOf(vanish.id))) + db.assertQuery(null, Filter(ids = listOf(note1.id))) + db.assertQuery(null, Filter(ids = listOf(note2.id))) + db.assertQuery(note3, Filter(ids = listOf(note3.id))) + + // trying to insert again should fail. + try { + db.insert(note1) + fail("Should not be able to insert a deleted event") + } catch (e: SQLiteConstraintException) { + assertEquals("blocked: a request to vanish event exists (code 1811 SQLITE_CONSTRAINT_TRIGGER)", e.message) + } + + db.assertQuery(vanish, Filter(ids = listOf(vanish.id))) + db.assertQuery(null, Filter(ids = listOf(note1.id))) + db.assertQuery(null, Filter(ids = listOf(note2.id))) + db.assertQuery(note3, Filter(ids = listOf(note3.id))) + } @Test - fun testInsertDeleteGiftWrap() { - val time = TimeUtils.now() + fun testInsertDeleteGiftWrap() = + forEachDB { db -> + val time = TimeUtils.now() - val me = NostrSignerSync() - val myFriend = NostrSignerSync() + val me = NostrSignerSync() + val myFriend = NostrSignerSync() - val note1 = me.sign(TextNoteEvent.build("test1", createdAt = time)) - val wrap1 = GiftWrapEvent.create(note1, me.pubKey) - val wrap2 = GiftWrapEvent.create(note1, myFriend.pubKey) + val note1 = me.sign(TextNoteEvent.build("test1", createdAt = time)) + val wrap1 = GiftWrapEvent.create(note1, me.pubKey) + val wrap2 = GiftWrapEvent.create(note1, myFriend.pubKey) - db.insert(wrap1) - db.insert(wrap2) - - db.assertQuery(wrap1, Filter(ids = listOf(wrap1.id))) - db.assertQuery(wrap2, Filter(ids = listOf(wrap2.id))) - - val randomVanishToWrap = signer.sign(RequestToVanishEvent.build("testUrl", createdAt = time + 2)) - - db.insert(randomVanishToWrap) - - db.assertQuery(wrap1, Filter(ids = listOf(wrap1.id))) - db.assertQuery(wrap2, Filter(ids = listOf(wrap2.id))) - - val vanish = me.sign(RequestToVanishEvent.build("testUrl", createdAt = time + 2)) - - db.insert(vanish) - - db.assertQuery(vanish, Filter(ids = listOf(vanish.id))) - db.assertQuery(null, Filter(ids = listOf(wrap1.id))) - db.assertQuery(wrap2, Filter(ids = listOf(wrap2.id))) - - // trying to insert again should fail. - try { db.insert(wrap1) - fail("Should not be able to insert a deleted event") - } catch (e: SQLiteConstraintException) { - assertEquals("blocked: a request to vanish event exists (code 1811 SQLITE_CONSTRAINT_TRIGGER)", e.message) - } + db.insert(wrap2) - db.assertQuery(vanish, Filter(ids = listOf(vanish.id))) - db.assertQuery(null, Filter(ids = listOf(wrap1.id))) - db.assertQuery(wrap2, Filter(ids = listOf(wrap2.id))) - } + db.assertQuery(wrap1, Filter(ids = listOf(wrap1.id))) + db.assertQuery(wrap2, Filter(ids = listOf(wrap2.id))) + + val randomVanishToWrap = signer.sign(RequestToVanishEvent.build("wss://quartz.local", createdAt = time + 2)) + + db.insert(randomVanishToWrap) + + db.assertQuery(wrap1, Filter(ids = listOf(wrap1.id))) + db.assertQuery(wrap2, Filter(ids = listOf(wrap2.id))) + + val vanish = me.sign(RequestToVanishEvent.build("wss://quartz.local", createdAt = time + 2)) + + db.insert(vanish) + + db.assertQuery(vanish, Filter(ids = listOf(vanish.id))) + db.assertQuery(null, Filter(ids = listOf(wrap1.id))) + db.assertQuery(wrap2, Filter(ids = listOf(wrap2.id))) + + // trying to insert again should fail. + try { + db.insert(wrap1) + fail("Should not be able to insert a deleted event") + } catch (e: SQLiteConstraintException) { + assertEquals("blocked: a request to vanish event exists (code 1811 SQLITE_CONSTRAINT_TRIGGER)", e.message) + } + + db.assertQuery(vanish, Filter(ids = listOf(vanish.id))) + db.assertQuery(null, Filter(ids = listOf(wrap1.id))) + db.assertQuery(wrap2, Filter(ids = listOf(wrap2.id))) + } } diff --git a/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/SearchTest.kt b/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/SearchTest.kt index f73a3372d..851c95417 100644 --- a/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/SearchTest.kt +++ b/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/SearchTest.kt @@ -20,20 +20,14 @@ */ package com.vitorpamplona.quartz.nip01Core.store.sqlite -import android.content.Context -import androidx.test.core.app.ApplicationProvider import com.vitorpamplona.quartz.nip01Core.metadata.MetadataEvent import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent import com.vitorpamplona.quartz.nip22Comments.CommentEvent -import org.junit.After -import org.junit.Before import org.junit.Test -class SearchTest { - private lateinit var db: SQLiteEventStore - - companion object Companion { +class SearchTest : BaseDBTest() { + companion object { val profile = MetadataEvent( id = "490d7439e530423f2540d4f2bdb73a0a2935f3df9e1f2a6f699a140c7db311fe", @@ -74,35 +68,25 @@ class SearchTest { ) } - @Before - fun setup() { - val context = ApplicationProvider.getApplicationContext() - db = SQLiteEventStore(context, null) - } - - @After - fun tearDown() { - db.close() - } - @Test - fun testTagWithSearch() { - db.insertEvent(comment) - db.insertEvent(profile) + fun testTagWithSearch() = + forEachDB { db -> + db.store.insertEvent(comment) + db.store.insertEvent(profile) - db.assertQuery(null, Filter(search = "testing1")) - db.assertQuery(comment, Filter(search = "testing")) - db.assertQuery(comment, Filter(kinds = listOf(CommentEvent.KIND), search = "testing")) - db.assertQuery(null, Filter(kinds = listOf(TextNoteEvent.KIND), search = "testing")) + db.assertQuery(null, Filter(search = "testing1")) + db.assertQuery(comment, Filter(search = "testing")) + db.assertQuery(comment, Filter(kinds = listOf(CommentEvent.KIND), search = "testing")) + db.assertQuery(null, Filter(kinds = listOf(TextNoteEvent.KIND), search = "testing")) - db.delete(comment.id) + db.store.delete(comment.id) - db.assertQuery(null, Filter(search = "testing")) - db.assertQuery(null, Filter(kinds = listOf(CommentEvent.KIND), search = "testing")) + db.assertQuery(null, Filter(search = "testing")) + db.assertQuery(null, Filter(kinds = listOf(CommentEvent.KIND), search = "testing")) - db.insertEvent(comment) + db.store.insertEvent(comment) - db.assertQuery(comment, Filter(search = "testing")) - db.assertQuery(comment, Filter(kinds = listOf(CommentEvent.KIND), search = "testing")) - } + db.assertQuery(comment, Filter(search = "testing")) + db.assertQuery(comment, Filter(kinds = listOf(CommentEvent.KIND), search = "testing")) + } } diff --git a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/EventIndexesModule.kt b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/EventIndexesModule.kt index e96c9f93c..4dbe73aa4 100644 --- a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/EventIndexesModule.kt +++ b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/EventIndexesModule.kt @@ -29,7 +29,7 @@ import com.vitorpamplona.quartz.nip59Giftwrap.wraps.GiftWrapEvent class EventIndexesModule( val hasher: (db: SQLiteDatabase) -> TagNameValueHasher, - val tagIndexStrategy: IndexingStrategy = DefaultIndexingStrategy(), + val indexStrategy: IndexingStrategy = DefaultIndexingStrategy(), ) : IModule { override fun create(db: SQLiteDatabase) { db.execSQL( @@ -67,18 +67,38 @@ class EventIndexesModule( // queries by ID (load events) db.execSQL("CREATE UNIQUE INDEX event_headers_id ON event_headers (id)") - // queries by limit (latest records), since, until (sync all) alone - db.execSQL("CREATE INDEX query_by_created_at_id ON event_headers (created_at DESC, id)") + val orderBy = + if (indexStrategy.useAndIndexIdOnOrderBy) { + "created_at DESC, id ASC" + } else { + "created_at DESC" + } + + // queries by limit (latest records), since, until (sync all) alone without any filter by kind.. rare + // serves as fall back for the lack of query_by_tags_hash index by default + db.execSQL("CREATE INDEX query_by_created_at_id ON event_headers ($orderBy)") + + // queries by kind only, mostly used in Global Feeds when author is not important. + db.execSQL("CREATE INDEX query_by_kind_created ON event_headers (kind, $orderBy)") // queries by kind + pubkey, but not d-tag, even if they are replaceables and addressables, by date. - db.execSQL("CREATE INDEX query_by_kind_pubkey_created ON event_headers (kind, pubkey, created_at DESC)") + db.execSQL("CREATE INDEX query_by_kind_pubkey_created ON event_headers (kind, pubkey, $orderBy)") // makes deletions on the event_header fast db.execSQL("CREATE INDEX fk_event_tags_header_id ON event_tags (event_header_row_id)") - // This is a very slow index to build (80% of the insert time goes here) but it is extremely effective. - db.execSQL("CREATE INDEX query_by_tags_hash ON event_tags (tag_hash, created_at DESC)") + // --------------------------------------------------------------- + // This are a very slow indexes (80% of the insert time goes here) + // --------------------------------------------------------------- + if (indexStrategy.indexTagQueriesWithoutKinds) { + // First one is only needed if the user is searching by tags without a kind. + db.execSQL("CREATE INDEX query_by_tags_hash ON event_tags (tag_hash, created_at DESC)") + } + + // This is the default index for most clients: tags by specific kinds that are supported by the client. db.execSQL("CREATE INDEX query_by_tags_hash_kind ON event_tags (tag_hash, kind, created_at DESC)") + + // this one is to allow search of tags by kind and author at the same time: DMs, reports, db.execSQL("CREATE INDEX query_by_tags_hash_kind_pubkey ON event_tags (tag_hash, kind, pubkey_hash, created_at DESC)") // Prevent updates to maintain immutability @@ -173,7 +193,7 @@ class EventIndexesModule( // rebalancing the tree every new insert val indexableTags = ArrayList() for (idx in event.tags.indices) { - if (tagIndexStrategy.shouldIndex(event.kind, event.tags[idx])) { + if (indexStrategy.shouldIndex(event.kind, event.tags[idx])) { indexableTags.add(hasher.hash(event.tags[idx][0], event.tags[idx][1])) } } diff --git a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/EventStore.kt b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/EventStore.kt index a4c85102e..53653f55d 100644 --- a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/EventStore.kt +++ b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/EventStore.kt @@ -29,9 +29,9 @@ class EventStore( context: Context, dbName: String? = "events.db", val relayUrl: String? = "wss://quartz.local", - val tagIndexStrategy: IndexingStrategy = DefaultIndexingStrategy(), + val indexStrategy: IndexingStrategy = DefaultIndexingStrategy(), ) : IEventStore { - val store = SQLiteEventStore(context, dbName, relayUrl, tagIndexStrategy) + val store = SQLiteEventStore(context, dbName, relayUrl, indexStrategy) override fun insert(event: Event) = store.insertEvent(event) diff --git a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/IndexingStrategy.kt b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/IndexingStrategy.kt index 4e50b4225..1f5cf7745 100644 --- a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/IndexingStrategy.kt +++ b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/IndexingStrategy.kt @@ -23,6 +23,9 @@ package com.vitorpamplona.quartz.nip01Core.store.sqlite import com.vitorpamplona.quartz.nip01Core.core.Tag interface IndexingStrategy { + val indexTagQueriesWithoutKinds: Boolean + val useAndIndexIdOnOrderBy: Boolean + fun shouldIndex( kind: Int, tag: Tag, @@ -32,7 +35,10 @@ interface IndexingStrategy { /** * By default, we index all tags that have a single letter name and some value */ -class DefaultIndexingStrategy : IndexingStrategy { +class DefaultIndexingStrategy( + override val indexTagQueriesWithoutKinds: Boolean = false, + override val useAndIndexIdOnOrderBy: Boolean = false, +) : IndexingStrategy { override fun shouldIndex( kind: Int, tag: Tag, diff --git a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryBuilder.kt b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryBuilder.kt index 29bbf3f54..b782ab5f5 100644 --- a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryBuilder.kt +++ b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryBuilder.kt @@ -23,6 +23,8 @@ package com.vitorpamplona.quartz.nip01Core.store.sqlite import android.database.Cursor import android.database.sqlite.SQLiteDatabase import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.core.HexKey +import com.vitorpamplona.quartz.nip01Core.core.Kind import com.vitorpamplona.quartz.nip01Core.core.OptimizedJsonMapper import com.vitorpamplona.quartz.nip01Core.core.isAddressable import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter @@ -34,6 +36,7 @@ import kotlin.collections.component2 class QueryBuilder( val fts: FullTextSearchModule, val hasher: (db: SQLiteDatabase) -> TagNameValueHasher, + val indexStrategy: IndexingStrategy, ) { // ------------ // Main methods @@ -110,13 +113,37 @@ class QueryBuilder( filter: Filter, hasher: TagNameValueHasher, ): QuerySpec { + val newFilter = filter.toFilterWithDTags() + + if (newFilter.isSimpleQuery()) { + return makeSimpleQuery( + ids = newFilter.ids, + authors = newFilter.authors, + kinds = newFilter.kinds, + dTags = newFilter.dTags, + since = newFilter.since, + until = newFilter.until, + limit = newFilter.limit, + ) + } + + if (newFilter.isSimpleSearch()) { + return makeSimpleSearch( + search = newFilter.search!!, + ids = newFilter.ids, + authors = newFilter.authors, + kinds = newFilter.kinds, + dTags = newFilter.dTags, + since = newFilter.since, + until = newFilter.until, + limit = newFilter.limit, + ) + } + val rowIdSubqueries = prepareRowIDSubQueries(filter, hasher) return if (rowIdSubqueries == null) { - QuerySpec( - makeEverythingQuery(), - emptyList(), - ) + QuerySpec(makeEverythingQuery()) } else { QuerySpec( makeQueryIn(rowIdSubqueries.sql), @@ -129,6 +156,8 @@ class QueryBuilder( filters: List, hasher: TagNameValueHasher, ): QuerySpec { + if (filters.size == 1) return toSql(filters.first(), hasher) + val rowIdSubqueries = unionSubqueriesIfNeeded(filters, hasher) return if (rowIdSubqueries == null) { @@ -144,7 +173,7 @@ class QueryBuilder( } } - private fun makeEverythingQuery() = "SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers ORDER BY created_at DESC, id" + private fun makeEverythingQuery() = "SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers ORDER BY created_at DESC${if (indexStrategy.useAndIndexIdOnOrderBy) ", id ASC" else ""}" private fun makeQueryIn(rowIdQuery: String) = """ @@ -153,7 +182,7 @@ class QueryBuilder( $rowIdQuery ) AS filtered ON event_headers.row_id = filtered.row_id - ORDER BY created_at DESC, id + ORDER BY created_at DESC${if (indexStrategy.useAndIndexIdOnOrderBy) ", id ASC" else ""} """.trimIndent() private fun SQLiteDatabase.runQuery(query: QuerySpec): List = @@ -359,12 +388,12 @@ class QueryBuilder( buildString { // always do tags if there are any if (reverseLookup) { - append("SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags ") + append("SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags") // it's quite rare to have 2 tags in the filter, but possible nonDTagsIn.keys.forEachIndexed { index, tagName -> if (defaultTagKey != null) { - append("INNER JOIN event_tags as event_tagsIn$index ON event_tagsIn$index.event_header_row_id = event_tags.event_header_row_id AND event_tagsIn$index.created_at = event_tags.created_at ") + append(" INNER JOIN event_tags as event_tagsIn$index ON event_tagsIn$index.event_header_row_id = event_tags.event_header_row_id AND event_tagsIn$index.created_at = event_tags.created_at") } else { defaultTagKey = TagNameForQuery.InTags(tagName) } @@ -373,7 +402,7 @@ class QueryBuilder( nonDTagsAll.keys.forEachIndexed { index, tagName -> nonDTagsAll[tagName]!!.forEachIndexed { valueIndex, tagValue -> if (defaultTagKey != null) { - append("INNER JOIN event_tags as event_tagsAll${index}_$valueIndex ON event_tagsAll${index}_$valueIndex.event_header_row_id = event_tags.event_header_row_id AND event_tagsAll${index}_$valueIndex.created_at = event_tags.created_at ") + append(" INNER JOIN event_tags as event_tagsAll${index}_$valueIndex ON event_tagsAll${index}_$valueIndex.event_header_row_id = event_tags.event_header_row_id AND event_tagsAll${index}_$valueIndex.created_at = event_tags.created_at") } else { defaultTagKey = TagNameForQuery.AllTags(tagName, valueIndex) } @@ -381,21 +410,21 @@ class QueryBuilder( } if (needHeaders) { - append("INNER JOIN event_headers ON event_headers.row_id = event_tags.event_header_row_id ") + append(" INNER JOIN event_headers ON event_headers.row_id = event_tags.event_header_row_id") } if (mustJoinSearch) { - append("INNER JOIN ${fts.tableName} ON ${fts.tableName}.${fts.eventHeaderRowIdName} = event_tags.event_header_row_id ") + append(" INNER JOIN ${fts.tableName} ON ${fts.tableName}.${fts.eventHeaderRowIdName} = event_tags.event_header_row_id") } } else if (mustJoinSearch) { - append("SELECT ${fts.tableName}.${fts.eventHeaderRowIdName} as row_id FROM ${fts.tableName} ") + append("SELECT ${fts.tableName}.${fts.eventHeaderRowIdName} as row_id FROM ${fts.tableName}") if (hasHeaders) { - append("INNER JOIN event_headers ON event_headers.row_id = ${fts.tableName}.${fts.eventHeaderRowIdName}") + append(" INNER JOIN event_headers ON event_headers.row_id = ${fts.tableName}.${fts.eventHeaderRowIdName}") } } else { // no tags and no search. - append("SELECT event_headers.row_id as row_id FROM event_headers ") + append("SELECT event_headers.row_id as row_id FROM event_headers") } } @@ -480,22 +509,183 @@ class QueryBuilder( } } - val whereClause = - if (filter.limit != null) { - if (reverseLookup) { - "${clause.conditions} ORDER BY event_tags.created_at DESC LIMIT ${filter.limit}" - } else { - "${clause.conditions} ORDER BY event_headers.created_at DESC, event_headers.id ASC LIMIT ${filter.limit}" + val sql = + buildString { + append(projection) + if (clause.conditions.isNotEmpty()) { + append(" WHERE ${clause.conditions}") + } + if (filter.limit != null) { + if (reverseLookup) { + append(" ORDER BY event_tags.created_at DESC") + append(" LIMIT ") + append(filter.limit) + } else { + append(" ORDER BY event_headers.created_at DESC") + append(" LIMIT ") + append(filter.limit) + } } - } else { - clause.conditions } - return QuerySpec("$projection WHERE $whereClause", clause.args) + return QuerySpec(sql, clause.args) } + private fun makeSimpleSearch( + search: String, + ids: List? = null, + authors: List? = null, + kinds: List? = null, + dTags: List? = null, + since: Long? = null, + until: Long? = null, + limit: Int? = null, + ): QuerySpec { + val clause = + where { + // the order should match indexes + // ids reduce the filter the most + ids?.let { equalsOrIn("event_headers.id", it) } + + match(fts.tableName, search) + + kinds?.let { equalsOrIn("event_headers.kind", it) } + authors?.let { equalsOrIn("event_headers.pubkey", it) } + + // there are indexes for these, starting with tags. + dTags?.let { equalsOrIn("event_headers.d_tag", it) } + + since?.let { greaterThanOrEquals("event_headers.created_at", it) } + until?.let { lessThanOrEquals("event_headers.created_at", it) } + + // if this is a dTag filter, it is likely that all kinds are addressables + // and so force the use of the addressable index + if (dTags != null && kinds != null) { + if (kinds.all { it.isAddressable() }) { + // matches unique index kind >= 30000 AND kind < 40000 + raw("(event_headers.kind >= 30000 AND kind < 40000)") + } + } + } + + val sql = + buildString { + append("SELECT event_headers.id, event_headers.pubkey, event_headers.created_at, event_headers.kind, event_headers.tags, event_headers.content, event_headers.sig FROM event_headers") + append("\nINNER JOIN ${fts.tableName} ON event_headers.row_id = ${fts.tableName}.${fts.eventHeaderRowIdName}") + if (clause.conditions.isNotEmpty()) { + append("\nWHERE ${clause.conditions}") + } + append("\nORDER BY event_headers.created_at DESC") + if (indexStrategy.useAndIndexIdOnOrderBy) { + append(", event_headers.id ASC") + } + if (limit != null) { + append("\nLIMIT ") + append(limit) + } + } + + println(sql) + + return QuerySpec(sql, clause.args) + } + + private fun makeSimpleQuery( + ids: List? = null, + authors: List? = null, + kinds: List? = null, + dTags: List? = null, + since: Long? = null, + until: Long? = null, + limit: Int? = null, + ): QuerySpec { + val clause = + where { + // the order should match indexes + // ids reduce the filter the most + ids?.let { equalsOrIn("id", it) } + + kinds?.let { equalsOrIn("kind", it) } + authors?.let { equalsOrIn("pubkey", it) } + + // there are indexes for these, starting with tags. + dTags?.let { equalsOrIn("d_tag", it) } + + since?.let { greaterThanOrEquals("created_at", it) } + until?.let { lessThanOrEquals("created_at", it) } + + // if this is a dTag filter, it is likely that all kinds are addressables + // and so force the use of the addressable index + if (dTags != null && kinds != null) { + if (kinds.all { it.isAddressable() }) { + // matches unique index kind >= 30000 AND kind < 40000 + raw("(kind >= 30000 AND kind < 40000)") + } + } + } + + val sql = + buildString { + append("SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers") + if (clause.conditions.isNotEmpty()) { + append("\nWHERE ") + append(clause.conditions) + } + append("\nORDER BY created_at DESC") + if (indexStrategy.useAndIndexIdOnOrderBy) { + append(", event_headers.id ASC") + } + if (limit != null) { + append("\nLIMIT ") + append(limit) + } + } + + println(sql) + + return QuerySpec(sql, clause.args) + } + + class FilterWithDTags( + val ids: List? = null, + val authors: List? = null, + val kinds: List? = null, + val dTags: List? = null, + val nonDTagsIn: Map>? = null, + val nonDTagsAll: Map>? = null, + val since: Long? = null, + val until: Long? = null, + val limit: Int? = null, + val search: String? = null, + ) { + fun isSimpleSearch() = + search != null && search.isNotEmpty() && + (nonDTagsIn == null || nonDTagsIn.isEmpty()) && + (nonDTagsAll == null || nonDTagsAll.isEmpty()) + + // can be resolved with just event_headers + fun isSimpleQuery() = + (nonDTagsIn == null || nonDTagsIn.isEmpty()) && + (nonDTagsAll == null || nonDTagsAll.isEmpty()) && + (search == null || search.isEmpty()) + } + + fun Filter.toFilterWithDTags(): FilterWithDTags = + FilterWithDTags( + ids = ids, + authors = authors, + kinds = kinds, + dTags = tags?.get("d") ?: tagsAll?.get("d"), + nonDTagsIn = tags?.filter { it.key != "d" }?.ifEmpty { null }, + nonDTagsAll = tagsAll?.filter { it.key != "d" }?.ifEmpty { null }, + since = since, + until = until, + limit = limit, + search = search, + ) + data class QuerySpec( val sql: String, - val args: List, + val args: List = emptyList(), ) } diff --git a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/SQLiteEventStore.kt b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/SQLiteEventStore.kt index bc9c837e4..ff02edf6b 100644 --- a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/SQLiteEventStore.kt +++ b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/SQLiteEventStore.kt @@ -41,7 +41,7 @@ class SQLiteEventStore( val context: Context, val dbName: String? = "events.db", val relayUrl: String? = null, - val tagIndexStrategy: IndexingStrategy = DefaultIndexingStrategy(), + val indexStrategy: IndexingStrategy = DefaultIndexingStrategy(), ) : SQLiteOpenHelper(context, dbName, null, DATABASE_VERSION) { companion object { const val DATABASE_VERSION = 2 @@ -50,7 +50,7 @@ class SQLiteEventStore( val seedModule = SeedModule() val fullTextSearchModule = FullTextSearchModule() - val eventIndexModule = EventIndexesModule(seedModule::hasher, tagIndexStrategy) + val eventIndexModule = EventIndexesModule(seedModule::hasher, indexStrategy) val replaceableModule = ReplaceableModule() val addressableModule = AddressableModule() @@ -60,7 +60,7 @@ class SQLiteEventStore( val expirationModule = ExpirationModule() val rightToVanishModule = RightToVanishModule(seedModule::hasher) - val queryBuilder = QueryBuilder(fullTextSearchModule, seedModule::hasher) + val queryBuilder = QueryBuilder(fullTextSearchModule, seedModule::hasher, indexStrategy) val modules = listOf( diff --git a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/sql/Condition.kt b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/sql/Condition.kt index 738cef423..dd4eb90ca 100644 --- a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/sql/Condition.kt +++ b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/sql/Condition.kt @@ -85,4 +85,6 @@ sealed class Condition { data class Or( val conditions: List, ) : Condition() + + class Empty : Condition() } diff --git a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/sql/SqlSelectionBuilder.kt b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/sql/SqlSelectionBuilder.kt index 78606720d..b109aff26 100644 --- a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/sql/SqlSelectionBuilder.kt +++ b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/sql/SqlSelectionBuilder.kt @@ -38,6 +38,9 @@ class SqlSelectionBuilder( */ private fun buildCondition(cond: Condition): String = when (cond) { + is Condition.Empty -> { + "" + } is Condition.Raw -> { cond.condition } diff --git a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/sql/WhereClauseBuilder.kt b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/sql/WhereClauseBuilder.kt index 1a42921f6..0cb89f573 100644 --- a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/sql/WhereClauseBuilder.kt +++ b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/sql/WhereClauseBuilder.kt @@ -119,7 +119,7 @@ class WhereClauseBuilder { } fun where(block: WhereClauseBuilder.() -> Unit): WhereClause { - val condition = WhereClauseBuilder().apply(block).buildAnd() ?: Condition.And(emptyList()) + val condition = WhereClauseBuilder().apply(block).buildAnd() ?: Condition.Empty() return SqlSelectionBuilder(condition).build() } From 98ba083172c4ad8a6e5c2f327ad2eebeb929ea75 Mon Sep 17 00:00:00 2001 From: Crowdin Bot Date: Fri, 2 Jan 2026 19:56:51 +0000 Subject: [PATCH 31/63] New Crowdin translations by GitHub Action --- amethyst/src/main/res/values-zh-rCN/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/amethyst/src/main/res/values-zh-rCN/strings.xml b/amethyst/src/main/res/values-zh-rCN/strings.xml index cb23aebc8..714143826 100644 --- a/amethyst/src/main/res/values-zh-rCN/strings.xml +++ b/amethyst/src/main/res/values-zh-rCN/strings.xml @@ -158,6 +158,7 @@ 录制消息 录制消息 点按以录制消息 + 重新录制 正在录制 正在录制 %1$s 上传中… From 48e791c634c9f989642015c5fb8513c83758c384 Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Fri, 2 Jan 2026 16:17:58 -0500 Subject: [PATCH 32/63] removes logs --- .../quartz/nip01Core/store/sqlite/QueryBuilder.kt | 4 ---- 1 file changed, 4 deletions(-) diff --git a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryBuilder.kt b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryBuilder.kt index b782ab5f5..39701d74c 100644 --- a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryBuilder.kt +++ b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryBuilder.kt @@ -585,8 +585,6 @@ class QueryBuilder( } } - println(sql) - return QuerySpec(sql, clause.args) } @@ -641,8 +639,6 @@ class QueryBuilder( } } - println(sql) - return QuerySpec(sql, clause.args) } From 989c63a71777573b1ffa91675123dd6e6a33b4ef Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Fri, 2 Jan 2026 16:57:49 -0500 Subject: [PATCH 33/63] Expose query plans with the current hasher --- .../quartz/nip01Core/store/sqlite/SQLiteEventStore.kt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/SQLiteEventStore.kt b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/SQLiteEventStore.kt index ff02edf6b..515d492c4 100644 --- a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/SQLiteEventStore.kt +++ b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/SQLiteEventStore.kt @@ -214,6 +214,10 @@ class SQLiteEventStore( onEach: (RawEvent) -> Unit, ) = queryBuilder.rawQuery(filters, readableDatabase, onEach) + fun planQuery(filter: Filter) = queryBuilder.planQuery(filter, seedModule.hasher(readableDatabase), readableDatabase) + + fun planQuery(filters: List) = queryBuilder.planQuery(filters, seedModule.hasher(readableDatabase), readableDatabase) + fun count(filter: Filter): Int = queryBuilder.count(filter, readableDatabase) fun count(filters: List): Int = queryBuilder.count(filters, readableDatabase) From 51f9fdd58c514c6c58b293d81bd86786985950e9 Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Fri, 2 Jan 2026 16:58:59 -0500 Subject: [PATCH 34/63] Adds a simple query to the count filter --- .../nip01Core/store/sqlite/QueryBuilder.kt | 33 ++++++++++++++++--- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryBuilder.kt b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryBuilder.kt index 39701d74c..53dd40202 100644 --- a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryBuilder.kt +++ b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryBuilder.kt @@ -117,6 +117,7 @@ class QueryBuilder( if (newFilter.isSimpleQuery()) { return makeSimpleQuery( + project = true, ids = newFilter.ids, authors = newFilter.authors, kinds = newFilter.kinds, @@ -250,6 +251,23 @@ class QueryBuilder( filter: Filter, db: SQLiteDatabase, ): Int { + val newFilter = filter.toFilterWithDTags() + + if (newFilter.isSimpleQuery()) { + val sql = + makeSimpleQuery( + project = false, + ids = newFilter.ids, + authors = newFilter.authors, + kinds = newFilter.kinds, + dTags = newFilter.dTags, + since = newFilter.since, + until = newFilter.until, + limit = newFilter.limit, + ) + return db.runCount(sql.sql, sql.args) + } + val rowIdSubQuery = prepareRowIDSubQueries(filter, hasher(db)) return if (rowIdSubQuery == null) { @@ -589,6 +607,7 @@ class QueryBuilder( } private fun makeSimpleQuery( + project: Boolean, ids: List? = null, authors: List? = null, kinds: List? = null, @@ -624,14 +643,20 @@ class QueryBuilder( val sql = buildString { - append("SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers") + if (project) { + append("SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers") + } else { + append("SELECT count(*) FROM event_headers") + } if (clause.conditions.isNotEmpty()) { append("\nWHERE ") append(clause.conditions) } - append("\nORDER BY created_at DESC") - if (indexStrategy.useAndIndexIdOnOrderBy) { - append(", event_headers.id ASC") + if (project) { + append("\nORDER BY created_at DESC") + if (indexStrategy.useAndIndexIdOnOrderBy) { + append(", event_headers.id ASC") + } } if (limit != null) { append("\nLIMIT ") From 7a34b8480e6b544e725620cd47a22745a00c20ed Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Fri, 2 Jan 2026 17:22:18 -0500 Subject: [PATCH 35/63] Fixes count not working for LIMIT queries --- .../quartz/nip01Core/store/sqlite/QueryBuilder.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryBuilder.kt b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryBuilder.kt index 53dd40202..ef4467b84 100644 --- a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryBuilder.kt +++ b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryBuilder.kt @@ -265,7 +265,7 @@ class QueryBuilder( until = newFilter.until, limit = newFilter.limit, ) - return db.runCount(sql.sql, sql.args) + return db.countIn(sql.sql, sql.args) } val rowIdSubQuery = prepareRowIDSubQueries(filter, hasher(db)) @@ -646,7 +646,7 @@ class QueryBuilder( if (project) { append("SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers") } else { - append("SELECT count(*) FROM event_headers") + append("SELECT row_id FROM event_headers") } if (clause.conditions.isNotEmpty()) { append("\nWHERE ") From c878b07458869d3d81394ec35fd5b94241a2ef5f Mon Sep 17 00:00:00 2001 From: Crowdin Bot Date: Sat, 3 Jan 2026 19:54:51 +0000 Subject: [PATCH 36/63] New Crowdin translations by GitHub Action --- amethyst/src/main/res/values-hu-rHU/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/amethyst/src/main/res/values-hu-rHU/strings.xml b/amethyst/src/main/res/values-hu-rHU/strings.xml index fda052418..b64c49bbf 100644 --- a/amethyst/src/main/res/values-hu-rHU/strings.xml +++ b/amethyst/src/main/res/values-hu-rHU/strings.xml @@ -158,6 +158,7 @@ Hangüzenet rögzítése Hangüzenet rögzítése Hangüzenet rögzítéséhez kattintson és tartsa lenyomva a gombot + Újrarögzítés Rögzítés %1$s rögzítése Feltöltés… From d7888c57fa0e8c59f1f9fd6b0650e58faa8d61ff Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Sat, 3 Jan 2026 18:18:36 -0500 Subject: [PATCH 37/63] Creating additional configuration options and amplifying tests to a combination of all those options --- .../nip01Core/store/sqlite/BaseDBTest.kt | 43 +- .../nip01Core/store/sqlite/DeletionTest.kt | 42 +- .../store/sqlite/QueryAssemblerTest.kt | 1578 ++++++++++------- .../store/sqlite/DeletionRequestModule.kt | 35 +- .../store/sqlite/EventIndexesModule.kt | 19 +- .../store/sqlite/IndexingStrategy.kt | 61 +- .../nip01Core/store/sqlite/QueryBuilder.kt | 2 +- 7 files changed, 1105 insertions(+), 675 deletions(-) diff --git a/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/BaseDBTest.kt b/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/BaseDBTest.kt index a1fe2259a..6926af8de 100644 --- a/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/BaseDBTest.kt +++ b/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/BaseDBTest.kt @@ -26,19 +26,46 @@ import org.junit.After import org.junit.Before open class BaseDBTest { - private lateinit var dbs: Map + private lateinit var dbs: MutableMap + + fun DefaultIndexingStrategy.name(): String = + """ + indexEventsByCreatedAtAlone=$indexEventsByCreatedAtAlone + indexTagsByCreatedAtAlone=$indexTagsByCreatedAtAlone + indexTagsWithKindAndPubkey=$indexTagsWithKindAndPubkey + useAndIndexIdOnOrderBy=$useAndIndexIdOnOrderBy + """.trimIndent() @Before fun setup() { val context = ApplicationProvider.getApplicationContext() - dbs = - mapOf( - "Default" to EventStore(context, null, indexStrategy = DefaultIndexingStrategy(false, false)), - "IndexAll" to EventStore(context, null, indexStrategy = DefaultIndexingStrategy(true, false)), - "Order by ID" to EventStore(context, null, indexStrategy = DefaultIndexingStrategy(false, true)), - "IndexAll, Order by ID" to EventStore(context, null, indexStrategy = DefaultIndexingStrategy(true, true)), - ) + val booleans = listOf(true, false) + + dbs = mutableMapOf() + + // tests all possible DBs + for (indexEventsByCreatedAtAlone in booleans) { + for (indexTagsByCreatedAtAlone in booleans) { + for (indexTagsWithKindAndPubkey in booleans) { + for (useAndIndexIdOnOrderBy in booleans) { + val indexStrategy = + DefaultIndexingStrategy( + indexEventsByCreatedAtAlone, + indexTagsByCreatedAtAlone, + indexTagsWithKindAndPubkey, + useAndIndexIdOnOrderBy, + ) + dbs[indexStrategy.name()] = + EventStore( + context = context, + dbName = null, + indexStrategy = indexStrategy, + ) + } + } + } + } } @After diff --git a/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/DeletionTest.kt b/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/DeletionTest.kt index 9d1ffc3c3..0a0d9b90a 100644 --- a/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/DeletionTest.kt +++ b/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/DeletionTest.kt @@ -208,26 +208,32 @@ class DeletionTest : BaseDBTest() { @Test fun testTriggersIndexUsage() = forEachDB { db -> - val sql = - """ - SELECT 1 FROM event_tags - WHERE - event_tags.tag_hash IN (3221122, 223322) AND - event_tags.kind = 5 AND - event_tags.pubkey_hash = 22332323 AND - event_tags.created_at >= 1766686500 - """.trimIndent() + var sql = db.store.deletionModule.rejectDeletedEventsSQLTemplate() - val explainer = - db.store.explainQuery(sql) + sql = sql.replace("NEW.etag_hash", "3221122") + sql = sql.replace("NEW.atag_hash", "223322") + sql = sql.replace("NEW.pubkey_owner_hash", "22332323") + sql = sql.replace("NEW.created_at", "1766686500") - TestCase.assertEquals( - """ - ${sql.replace("\n","\n ")} - └── SEARCH event_tags USING COVERING INDEX query_by_tags_hash_kind_pubkey (tag_hash=? AND kind=? AND pubkey_hash=? AND created_at>?) - """.trimIndent(), - explainer, - ) + val explainer = db.store.explainQuery(sql) + + if (db.indexStrategy.indexTagsWithKindAndPubkey) { + TestCase.assertEquals( + """ + |$sql + |└── SEARCH event_tags USING COVERING INDEX query_by_tags_hash_kind_pubkey (tag_hash=? AND kind=? AND pubkey_hash=? AND created_at>?) + """.trimMargin(), + explainer, + ) + } else { + TestCase.assertEquals( + """ + |$sql + |└── SEARCH event_tags USING INDEX query_by_tags_hash_kind (tag_hash=? AND kind=? AND created_at>?) + """.trimMargin(), + explainer, + ) + } } @Test diff --git a/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryAssemblerTest.kt b/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryAssemblerTest.kt index 52d4c5423..3dd656c27 100644 --- a/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryAssemblerTest.kt +++ b/quartz/src/androidInstrumentedTest/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryAssemblerTest.kt @@ -20,8 +20,6 @@ */ package com.vitorpamplona.quartz.nip01Core.store.sqlite -import android.content.Context -import androidx.test.core.app.ApplicationProvider import com.vitorpamplona.quartz.experimental.relationshipStatus.ContactCardEvent import com.vitorpamplona.quartz.nip01Core.metadata.MetadataEvent import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter @@ -32,665 +30,991 @@ import com.vitorpamplona.quartz.nip50Search.SearchRelayListEvent import com.vitorpamplona.quartz.nip65RelayList.AdvertisedRelayListEvent import junit.framework.TestCase import junit.framework.TestCase.assertEquals -import org.junit.After import org.junit.Assert -import org.junit.Before import org.junit.Test -class QueryAssemblerTest { +class QueryAssemblerTest : BaseDBTest() { val hasher = TagNameValueHasher(0) val key1 = "7c5eb72a4584fdaaeaa145b25c92ea9917704224951219dbd43acef9e91fb88d" val key2 = "f3ac434d61bc0f491a814782ccfdf9c439dae1f0bde9097ad4a245f4c495cd14" val key3 = "12ae0fd81c85e1e7d9ed096397dc3129849425fe6f8afce7213ebf38ddfc6ca9" - private lateinit var dbAllIndexes: EventStore - private lateinit var dbNoKindIndexes: EventStore - - @Before - fun setup() { - val context = ApplicationProvider.getApplicationContext() - dbAllIndexes = EventStore(context, null, indexStrategy = DefaultIndexingStrategy(true)) - dbNoKindIndexes = EventStore(context, null, indexStrategy = DefaultIndexingStrategy(false)) - } - - @After - fun tearDown() { - dbAllIndexes.close() - dbNoKindIndexes.close() - } - fun EventStore.explain(f: Filter) = store.queryBuilder.planQuery(f, hasher, store.readableDatabase) fun EventStore.explain(f: List) = store.queryBuilder.planQuery(f, hasher, store.readableDatabase) @Test - fun testEmpty() { - Assert.assertEquals( - """ - SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers - ORDER BY created_at DESC - └── SCAN event_headers USING INDEX query_by_created_at_id - """.trimIndent(), - dbAllIndexes.explain(Filter()), - ) - - Assert.assertEquals( - """ - SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers - ORDER BY created_at DESC - └── SCAN event_headers USING INDEX query_by_created_at_id - """.trimIndent(), - dbNoKindIndexes.explain(Filter()), - ) - } + fun testEmpty() = + forEachDB { db -> + val orderBy = if (db.indexStrategy.useAndIndexIdOnOrderBy) "created_at DESC, id ASC" else "created_at DESC" + if (db.indexStrategy.indexEventsByCreatedAtAlone) { + Assert.assertEquals( + """ + SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers + ORDER BY $orderBy + └── SCAN event_headers USING INDEX query_by_created_at_id + """.trimIndent(), + db.explain(Filter()), + ) + } else { + Assert.assertEquals( + """ + SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers + ORDER BY $orderBy + ├── SCAN event_headers + └── USE TEMP B-TREE FOR ORDER BY + """.trimIndent(), + db.explain(Filter()), + ) + } + } @Test - fun testCheckDeletionEventExists() { - val filter = - Filter( - kinds = listOf(5), - authors = listOf(key1), - tags = mapOf("e" to listOf(key2)), - since = 1750889190, - ) - TestCase.assertEquals( - """ - SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers - INNER JOIN ( - SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags WHERE (event_tags.tag_hash = "2657743813502222172") AND (event_tags.kind = "5") AND (event_tags.pubkey_hash = "1730514094536529999") AND (event_tags.created_at >= "1750889190") - ) AS filtered - ON event_headers.row_id = filtered.row_id - ORDER BY created_at DESC - ├── CO-ROUTINE filtered - │ ├── SEARCH event_tags USING INDEX query_by_tags_hash_kind_pubkey (tag_hash=? AND kind=? AND pubkey_hash=? AND created_at>?) - │ └── USE TEMP B-TREE FOR DISTINCT - ├── SCAN filtered - ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) - └── USE TEMP B-TREE FOR ORDER BY - """.trimIndent(), - dbAllIndexes.explain(filter), - ) - - TestCase.assertEquals( - """ - SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers - INNER JOIN ( - SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags WHERE (event_tags.tag_hash = "2657743813502222172") AND (event_tags.kind = "5") AND (event_tags.pubkey_hash = "1730514094536529999") AND (event_tags.created_at >= "1750889190") - ) AS filtered - ON event_headers.row_id = filtered.row_id - ORDER BY created_at DESC - ├── CO-ROUTINE filtered - │ ├── SEARCH event_tags USING INDEX query_by_tags_hash_kind_pubkey (tag_hash=? AND kind=? AND pubkey_hash=? AND created_at>?) - │ └── USE TEMP B-TREE FOR DISTINCT - ├── SCAN filtered - ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) - └── USE TEMP B-TREE FOR ORDER BY - """.trimIndent(), - dbNoKindIndexes.explain(filter), - ) - } - - @Test - fun testLimit() { - val filter = Filter(limit = 10) - TestCase.assertEquals( - """ - SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers - ORDER BY created_at DESC - LIMIT 10 - └── SCAN event_headers USING INDEX query_by_created_at_id - """.trimIndent(), - dbAllIndexes.explain(filter), - ) - } - - @Test - fun testLimits() { - val filter = listOf(Filter(limit = 10), Filter(limit = 30)) - TestCase.assertEquals( - """ - SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers - INNER JOIN ( - SELECT row_id FROM (SELECT event_headers.row_id as row_id FROM event_headers ORDER BY event_headers.created_at DESC LIMIT 10) - UNION - SELECT row_id FROM (SELECT event_headers.row_id as row_id FROM event_headers ORDER BY event_headers.created_at DESC LIMIT 30) - ) AS filtered - ON event_headers.row_id = filtered.row_id - ORDER BY created_at DESC - ├── CO-ROUTINE filtered - │ └── COMPOUND QUERY - │ ├── LEFT-MOST SUBQUERY - │ │ ├── CO-ROUTINE (subquery-1) - │ │ │ └── SCAN event_headers USING COVERING INDEX query_by_created_at_id - │ │ └── SCAN (subquery-1) - │ └── UNION USING TEMP B-TREE - │ ├── CO-ROUTINE (subquery-3) - │ │ └── SCAN event_headers USING COVERING INDEX query_by_created_at_id - │ └── SCAN (subquery-3) - ├── SCAN filtered - ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) - └── USE TEMP B-TREE FOR ORDER BY - """.trimIndent(), - dbAllIndexes.explain(filter), - ) - } - - @Test - fun testAllFeatures() { - val filter = - listOf( - Filter(limit = 10), + fun testCheckDeletionEventExists() = + forEachDB { db -> + val filter = Filter( + kinds = listOf(5), authors = listOf(key1), - kinds = listOf(1, 1111), - search = "keywords", - limit = 100, - ), - Filter(kinds = listOf(20), search = "cats", limit = 30), - ) - TestCase.assertEquals( - """ - SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers - INNER JOIN ( - SELECT row_id FROM (SELECT event_headers.row_id as row_id FROM event_headers ORDER BY event_headers.created_at DESC LIMIT 10) - UNION - SELECT row_id FROM (SELECT event_fts.event_header_row_id as row_id FROM event_fts INNER JOIN event_headers ON event_headers.row_id = event_fts.event_header_row_id WHERE (event_headers.kind IN ("1", "1111")) AND (event_headers.pubkey = "7c5eb72a4584fdaaeaa145b25c92ea9917704224951219dbd43acef9e91fb88d") AND (event_fts MATCH "keywords") ORDER BY event_headers.created_at DESC LIMIT 100) - UNION - SELECT row_id FROM (SELECT event_fts.event_header_row_id as row_id FROM event_fts INNER JOIN event_headers ON event_headers.row_id = event_fts.event_header_row_id WHERE (event_headers.kind = "20") AND (event_fts MATCH "cats") ORDER BY event_headers.created_at DESC LIMIT 30) - ) AS filtered - ON event_headers.row_id = filtered.row_id - ORDER BY created_at DESC - ├── CO-ROUTINE filtered - │ └── COMPOUND QUERY - │ ├── LEFT-MOST SUBQUERY - │ │ ├── CO-ROUTINE (subquery-1) - │ │ │ └── SCAN event_headers USING COVERING INDEX query_by_created_at_id - │ │ └── SCAN (subquery-1) - │ ├── UNION USING TEMP B-TREE - │ │ ├── CO-ROUTINE (subquery-3) - │ │ │ ├── SCAN event_fts VIRTUAL TABLE INDEX 4: - │ │ │ ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) - │ │ │ └── USE TEMP B-TREE FOR ORDER BY - │ │ └── SCAN (subquery-3) - │ └── UNION USING TEMP B-TREE - │ ├── CO-ROUTINE (subquery-5) - │ │ ├── SEARCH event_headers USING COVERING INDEX query_by_kind_created (kind=?) - │ │ └── SCAN event_fts VIRTUAL TABLE INDEX 4: - │ └── SCAN (subquery-5) - ├── SCAN filtered - ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) - └── USE TEMP B-TREE FOR ORDER BY - """.trimIndent(), - dbAllIndexes.explain(filter), - ) - } + tags = mapOf("e" to listOf(key2)), + since = 1750889190, + ) + val orderBy = if (db.indexStrategy.useAndIndexIdOnOrderBy) "created_at DESC, id ASC" else "created_at DESC" + if (db.indexStrategy.indexTagsWithKindAndPubkey) { + TestCase.assertEquals( + """ + SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers + INNER JOIN ( + SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags WHERE (event_tags.tag_hash = "2657743813502222172") AND (event_tags.kind = "5") AND (event_tags.pubkey_hash = "1730514094536529999") AND (event_tags.created_at >= "1750889190") + ) AS filtered + ON event_headers.row_id = filtered.row_id + ORDER BY $orderBy + ├── CO-ROUTINE filtered + │ ├── SEARCH event_tags USING INDEX query_by_tags_hash_kind_pubkey (tag_hash=? AND kind=? AND pubkey_hash=? AND created_at>?) + │ └── USE TEMP B-TREE FOR DISTINCT + ├── SCAN filtered + ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) + └── USE TEMP B-TREE FOR ORDER BY + """.trimIndent(), + db.explain(filter), + ) + } else { + TestCase.assertEquals( + """ + SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers + INNER JOIN ( + SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags WHERE (event_tags.tag_hash = "2657743813502222172") AND (event_tags.kind = "5") AND (event_tags.pubkey_hash = "1730514094536529999") AND (event_tags.created_at >= "1750889190") + ) AS filtered + ON event_headers.row_id = filtered.row_id + ORDER BY $orderBy + ├── CO-ROUTINE filtered + │ ├── SEARCH event_tags USING INDEX query_by_tags_hash_kind (tag_hash=? AND kind=? AND created_at>?) + │ └── USE TEMP B-TREE FOR DISTINCT + ├── SCAN filtered + ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) + └── USE TEMP B-TREE FOR ORDER BY + """.trimIndent(), + db.explain(filter), + ) + } + } @Test - fun testSingleFilterConversionToSimpleQuery() { - val filter = - listOf( + fun testLimit() = + forEachDB { db -> + val filter = Filter(limit = 10) + val orderBy = if (db.indexStrategy.useAndIndexIdOnOrderBy) "created_at DESC, id ASC" else "created_at DESC" + + if (db.indexStrategy.indexEventsByCreatedAtAlone) { + TestCase.assertEquals( + """ + SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers + ORDER BY $orderBy + LIMIT 10 + └── SCAN event_headers USING INDEX query_by_created_at_id + """.trimIndent(), + db.explain(filter), + ) + } else { + TestCase.assertEquals( + """ + SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers + ORDER BY $orderBy + LIMIT 10 + ├── SCAN event_headers + └── USE TEMP B-TREE FOR ORDER BY + """.trimIndent(), + db.explain(filter), + ) + } + } + + @Test + fun testLimits() = + forEachDB { db -> + val filter = listOf(Filter(limit = 10), Filter(limit = 30)) + val orderBy = + if (db.indexStrategy.useAndIndexIdOnOrderBy) { + "created_at DESC, id ASC" + } else { + "created_at DESC" + } + if (db.indexStrategy.indexEventsByCreatedAtAlone) { + TestCase.assertEquals( + """ + SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers + INNER JOIN ( + SELECT row_id FROM (SELECT event_headers.row_id as row_id FROM event_headers ORDER BY event_headers.created_at DESC LIMIT 10) + UNION + SELECT row_id FROM (SELECT event_headers.row_id as row_id FROM event_headers ORDER BY event_headers.created_at DESC LIMIT 30) + ) AS filtered + ON event_headers.row_id = filtered.row_id + ORDER BY $orderBy + ├── CO-ROUTINE filtered + │ └── COMPOUND QUERY + │ ├── LEFT-MOST SUBQUERY + │ │ ├── CO-ROUTINE (subquery-1) + │ │ │ └── SCAN event_headers USING COVERING INDEX query_by_created_at_id + │ │ └── SCAN (subquery-1) + │ └── UNION USING TEMP B-TREE + │ ├── CO-ROUTINE (subquery-3) + │ │ └── SCAN event_headers USING COVERING INDEX query_by_created_at_id + │ └── SCAN (subquery-3) + ├── SCAN filtered + ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) + └── USE TEMP B-TREE FOR ORDER BY + """.trimIndent(), + db.explain(filter), + ) + } else { + TestCase.assertEquals( + """ + SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers + INNER JOIN ( + SELECT row_id FROM (SELECT event_headers.row_id as row_id FROM event_headers ORDER BY event_headers.created_at DESC LIMIT 10) + UNION + SELECT row_id FROM (SELECT event_headers.row_id as row_id FROM event_headers ORDER BY event_headers.created_at DESC LIMIT 30) + ) AS filtered + ON event_headers.row_id = filtered.row_id + ORDER BY $orderBy + ├── CO-ROUTINE filtered + │ └── COMPOUND QUERY + │ ├── LEFT-MOST SUBQUERY + │ │ ├── CO-ROUTINE (subquery-1) + │ │ │ ├── SCAN event_headers USING COVERING INDEX query_by_kind_created + │ │ │ └── USE TEMP B-TREE FOR ORDER BY + │ │ └── SCAN (subquery-1) + │ └── UNION USING TEMP B-TREE + │ ├── CO-ROUTINE (subquery-3) + │ │ ├── SCAN event_headers USING COVERING INDEX query_by_kind_created + │ │ └── USE TEMP B-TREE FOR ORDER BY + │ └── SCAN (subquery-3) + ├── SCAN filtered + ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) + └── USE TEMP B-TREE FOR ORDER BY + """.trimIndent(), + db.explain(filter), + ) + } + } + + @Test + fun testAllFeatures() = + forEachDB { db -> + val filter = + listOf( + Filter(limit = 10), + Filter( + authors = listOf(key1), + kinds = listOf(1, 1111), + search = "keywords", + limit = 100, + ), + Filter(kinds = listOf(20), search = "cats", limit = 30), + ) + val orderBy = if (db.indexStrategy.useAndIndexIdOnOrderBy) "created_at DESC, id ASC" else "created_at DESC" + if (db.indexStrategy.indexEventsByCreatedAtAlone) { + TestCase.assertEquals( + """ + SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers + INNER JOIN ( + SELECT row_id FROM (SELECT event_headers.row_id as row_id FROM event_headers ORDER BY event_headers.created_at DESC LIMIT 10) + UNION + SELECT row_id FROM (SELECT event_fts.event_header_row_id as row_id FROM event_fts INNER JOIN event_headers ON event_headers.row_id = event_fts.event_header_row_id WHERE (event_headers.kind IN ("1", "1111")) AND (event_headers.pubkey = "7c5eb72a4584fdaaeaa145b25c92ea9917704224951219dbd43acef9e91fb88d") AND (event_fts MATCH "keywords") ORDER BY event_headers.created_at DESC LIMIT 100) + UNION + SELECT row_id FROM (SELECT event_fts.event_header_row_id as row_id FROM event_fts INNER JOIN event_headers ON event_headers.row_id = event_fts.event_header_row_id WHERE (event_headers.kind = "20") AND (event_fts MATCH "cats") ORDER BY event_headers.created_at DESC LIMIT 30) + ) AS filtered + ON event_headers.row_id = filtered.row_id + ORDER BY $orderBy + ├── CO-ROUTINE filtered + │ └── COMPOUND QUERY + │ ├── LEFT-MOST SUBQUERY + │ │ ├── CO-ROUTINE (subquery-1) + │ │ │ └── SCAN event_headers USING COVERING INDEX query_by_created_at_id + │ │ └── SCAN (subquery-1) + │ ├── UNION USING TEMP B-TREE + │ │ ├── CO-ROUTINE (subquery-3) + │ │ │ ├── SCAN event_fts VIRTUAL TABLE INDEX 4: + │ │ │ ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) + │ │ │ └── USE TEMP B-TREE FOR ORDER BY + │ │ └── SCAN (subquery-3) + │ └── UNION USING TEMP B-TREE + │ ├── CO-ROUTINE (subquery-5) + │ │ ├── SEARCH event_headers USING COVERING INDEX query_by_kind_created (kind=?) + │ │ └── SCAN event_fts VIRTUAL TABLE INDEX 4: + │ └── SCAN (subquery-5) + ├── SCAN filtered + ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) + └── USE TEMP B-TREE FOR ORDER BY + """.trimIndent(), + db.explain(filter), + ) + } else { + TestCase.assertEquals( + """ + SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers + INNER JOIN ( + SELECT row_id FROM (SELECT event_headers.row_id as row_id FROM event_headers ORDER BY event_headers.created_at DESC LIMIT 10) + UNION + SELECT row_id FROM (SELECT event_fts.event_header_row_id as row_id FROM event_fts INNER JOIN event_headers ON event_headers.row_id = event_fts.event_header_row_id WHERE (event_headers.kind IN ("1", "1111")) AND (event_headers.pubkey = "7c5eb72a4584fdaaeaa145b25c92ea9917704224951219dbd43acef9e91fb88d") AND (event_fts MATCH "keywords") ORDER BY event_headers.created_at DESC LIMIT 100) + UNION + SELECT row_id FROM (SELECT event_fts.event_header_row_id as row_id FROM event_fts INNER JOIN event_headers ON event_headers.row_id = event_fts.event_header_row_id WHERE (event_headers.kind = "20") AND (event_fts MATCH "cats") ORDER BY event_headers.created_at DESC LIMIT 30) + ) AS filtered + ON event_headers.row_id = filtered.row_id + ORDER BY $orderBy + ├── CO-ROUTINE filtered + │ └── COMPOUND QUERY + │ ├── LEFT-MOST SUBQUERY + │ │ ├── CO-ROUTINE (subquery-1) + │ │ │ ├── SCAN event_headers USING COVERING INDEX query_by_kind_created + │ │ │ └── USE TEMP B-TREE FOR ORDER BY + │ │ └── SCAN (subquery-1) + │ ├── UNION USING TEMP B-TREE + │ │ ├── CO-ROUTINE (subquery-3) + │ │ │ ├── SCAN event_fts VIRTUAL TABLE INDEX 4: + │ │ │ ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) + │ │ │ └── USE TEMP B-TREE FOR ORDER BY + │ │ └── SCAN (subquery-3) + │ └── UNION USING TEMP B-TREE + │ ├── CO-ROUTINE (subquery-5) + │ │ ├── SEARCH event_headers USING COVERING INDEX query_by_kind_created (kind=?) + │ │ └── SCAN event_fts VIRTUAL TABLE INDEX 4: + │ └── SCAN (subquery-5) + ├── SCAN filtered + ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) + └── USE TEMP B-TREE FOR ORDER BY + """.trimIndent(), + db.explain(filter), + ) + } + } + + @Test + fun testSingleFilterConversionToSimpleQuery() = + forEachDB { db -> + val filter = + listOf( + Filter( + kinds = listOf(ContactListEvent.KIND), + limit = 30, + ), + ) + if (db.indexStrategy.useAndIndexIdOnOrderBy) { + TestCase.assertEquals( + """ + SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers + WHERE kind = "3" + ORDER BY created_at DESC, id ASC + LIMIT 30 + └── SEARCH event_headers USING INDEX query_by_kind_created (kind=?) + """.trimIndent(), + db.explain(filter), + ) + } else { + TestCase.assertEquals( + """ + SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers + WHERE kind = "3" + ORDER BY created_at DESC + LIMIT 30 + └── SEARCH event_headers USING INDEX query_by_kind_created (kind=?) + """.trimIndent(), + db.explain(filter), + ) + } + } + + @Test + fun testKinds() = + forEachDB { db -> + val filter = + listOf( + Filter( + kinds = listOf(ContactListEvent.KIND), + limit = 30, + ), + Filter( + kinds = listOf(TextNoteEvent.KIND), + limit = 30, + ), + ) + val orderBy = if (db.indexStrategy.useAndIndexIdOnOrderBy) "created_at DESC, id ASC" else "created_at DESC" + + TestCase.assertEquals( + """ + SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers + INNER JOIN ( + SELECT row_id FROM (SELECT event_headers.row_id as row_id FROM event_headers WHERE event_headers.kind = "3" ORDER BY event_headers.created_at DESC LIMIT 30) + UNION + SELECT row_id FROM (SELECT event_headers.row_id as row_id FROM event_headers WHERE event_headers.kind = "1" ORDER BY event_headers.created_at DESC LIMIT 30) + ) AS filtered + ON event_headers.row_id = filtered.row_id + ORDER BY $orderBy + ├── CO-ROUTINE filtered + │ └── COMPOUND QUERY + │ ├── LEFT-MOST SUBQUERY + │ │ ├── CO-ROUTINE (subquery-1) + │ │ │ └── SEARCH event_headers USING COVERING INDEX query_by_kind_created (kind=?) + │ │ └── SCAN (subquery-1) + │ └── UNION USING TEMP B-TREE + │ ├── CO-ROUTINE (subquery-3) + │ │ └── SEARCH event_headers USING COVERING INDEX query_by_kind_created (kind=?) + │ └── SCAN (subquery-3) + ├── SCAN filtered + ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) + └── USE TEMP B-TREE FOR ORDER BY + """.trimIndent(), + db.explain(filter), + ) + } + + @Test + fun testKindAndDTag() = + forEachDB { db -> + val filter = + listOf( + Filter( + kinds = listOf(ContactListEvent.KIND), + tags = mapOf("d" to listOf("")), + limit = 30, + ), + ) + if (db.indexStrategy.useAndIndexIdOnOrderBy) { + TestCase.assertEquals( + """ + SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers + WHERE (kind = "3") AND (d_tag = "") + ORDER BY created_at DESC, id ASC + LIMIT 30 + └── SEARCH event_headers USING INDEX query_by_kind_created (kind=?) + """.trimIndent(), + db.explain(filter), + ) + } else { + TestCase.assertEquals( + """ + SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers + WHERE (kind = "3") AND (d_tag = "") + ORDER BY created_at DESC + LIMIT 30 + └── SEARCH event_headers USING INDEX query_by_kind_created (kind=?) + """.trimIndent(), + db.explain(filter), + ) + } + } + + @Test + fun testFollowersOf() = + forEachDB { db -> + val filter = + listOf( + Filter( + kinds = listOf(ContactListEvent.KIND), + tags = mapOf("p" to listOf("460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c")), + limit = 30, + ), + ) + val orderBy = if (db.indexStrategy.useAndIndexIdOnOrderBy) "created_at DESC, id ASC" else "created_at DESC" + TestCase.assertEquals( + """ + SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers + INNER JOIN ( + SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags WHERE (event_tags.tag_hash = "-4551135004136952885") AND (event_tags.kind = "3") ORDER BY event_tags.created_at DESC LIMIT 30 + ) AS filtered + ON event_headers.row_id = filtered.row_id + ORDER BY $orderBy + ├── CO-ROUTINE filtered + │ ├── SEARCH event_tags USING INDEX query_by_tags_hash_kind (tag_hash=? AND kind=?) + │ └── USE TEMP B-TREE FOR DISTINCT + ├── SCAN filtered + ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) + └── USE TEMP B-TREE FOR ORDER BY + """.trimIndent(), + db.explain(filter), + ) + } + + @Test + fun testNotificationsOf() = + forEachDB { db -> + val filter = + listOf( + Filter( + tags = mapOf("p" to listOf("460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c")), + limit = 30, + ), + ) + val orderBy = if (db.indexStrategy.useAndIndexIdOnOrderBy) "created_at DESC, id ASC" else "created_at DESC" + if (db.indexStrategy.indexTagsByCreatedAtAlone) { + TestCase.assertEquals( + """ + SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers + INNER JOIN ( + SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags WHERE event_tags.tag_hash = "-4551135004136952885" ORDER BY event_tags.created_at DESC LIMIT 30 + ) AS filtered + ON event_headers.row_id = filtered.row_id + ORDER BY $orderBy + ├── CO-ROUTINE filtered + │ ├── SEARCH event_tags USING INDEX query_by_tags_hash (tag_hash=?) + │ └── USE TEMP B-TREE FOR DISTINCT + ├── SCAN filtered + ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) + └── USE TEMP B-TREE FOR ORDER BY + """.trimIndent(), + db.explain(filter), + ) + } else { + TestCase.assertEquals( + """ + SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers + INNER JOIN ( + SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags WHERE event_tags.tag_hash = "-4551135004136952885" ORDER BY event_tags.created_at DESC LIMIT 30 + ) AS filtered + ON event_headers.row_id = filtered.row_id + ORDER BY $orderBy + ├── CO-ROUTINE filtered + │ ├── SEARCH event_tags USING INDEX query_by_tags_hash_kind (tag_hash=?) + │ ├── USE TEMP B-TREE FOR DISTINCT + │ └── USE TEMP B-TREE FOR ORDER BY + ├── SCAN filtered + ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) + └── USE TEMP B-TREE FOR ORDER BY + """.trimIndent(), + db.explain(filter), + ) + } + } + + @Test + fun testTagsAndKinds() = + forEachDB { db -> + val filter = + listOf( + Filter( + kinds = listOf(ContactListEvent.KIND), + tags = mapOf("p" to listOf("460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c")), + limit = 30, + ), + ) + val orderBy = if (db.indexStrategy.useAndIndexIdOnOrderBy) "created_at DESC, id ASC" else "created_at DESC" + TestCase.assertEquals( + """ + SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers + INNER JOIN ( + SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags WHERE (event_tags.tag_hash = "-4551135004136952885") AND (event_tags.kind = "3") ORDER BY event_tags.created_at DESC LIMIT 30 + ) AS filtered + ON event_headers.row_id = filtered.row_id + ORDER BY $orderBy + ├── CO-ROUTINE filtered + │ ├── SEARCH event_tags USING INDEX query_by_tags_hash_kind (tag_hash=? AND kind=?) + │ └── USE TEMP B-TREE FOR DISTINCT + ├── SCAN filtered + ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) + └── USE TEMP B-TREE FOR ORDER BY + """.trimIndent(), + db.explain(filter), + ) + } + + @Test + fun testTagsAndAuthors() = + forEachDB { db -> + val filter = + listOf( + Filter( + authors = listOf(key1), + tags = mapOf("p" to listOf("460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c")), + limit = 30, + ), + ) + val orderBy = if (db.indexStrategy.useAndIndexIdOnOrderBy) "created_at DESC, id ASC" else "created_at DESC" + if (db.indexStrategy.indexTagsByCreatedAtAlone) { + TestCase.assertEquals( + """ + SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers + INNER JOIN ( + SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags WHERE (event_tags.tag_hash = "-4551135004136952885") AND (event_tags.pubkey_hash = "1730514094536529999") ORDER BY event_tags.created_at DESC LIMIT 30 + ) AS filtered + ON event_headers.row_id = filtered.row_id + ORDER BY $orderBy + ├── CO-ROUTINE filtered + │ ├── SEARCH event_tags USING INDEX query_by_tags_hash (tag_hash=?) + │ └── USE TEMP B-TREE FOR DISTINCT + ├── SCAN filtered + ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) + └── USE TEMP B-TREE FOR ORDER BY + """.trimIndent(), + db.explain(filter), + ) + } else { + TestCase.assertEquals( + """ + SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers + INNER JOIN ( + SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags WHERE (event_tags.tag_hash = "-4551135004136952885") AND (event_tags.pubkey_hash = "1730514094536529999") ORDER BY event_tags.created_at DESC LIMIT 30 + ) AS filtered + ON event_headers.row_id = filtered.row_id + ORDER BY $orderBy + ├── CO-ROUTINE filtered + │ ├── SEARCH event_tags USING INDEX query_by_tags_hash_kind (tag_hash=?) + │ ├── USE TEMP B-TREE FOR DISTINCT + │ └── USE TEMP B-TREE FOR ORDER BY + ├── SCAN filtered + ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) + └── USE TEMP B-TREE FOR ORDER BY + """.trimIndent(), + db.explain(filter), + ) + } + } + + @Test + fun testTwoTags() = + forEachDB { db -> + val filter = + listOf( + Filter( + kinds = listOf(1), + tags = + mapOf( + "p" to listOf("460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c"), + "t" to listOf("hashtag"), + ), + limit = 30, + ), + ) + val orderBy = if (db.indexStrategy.useAndIndexIdOnOrderBy) "created_at DESC, id ASC" else "created_at DESC" + if (db.indexStrategy.indexTagsByCreatedAtAlone) { + TestCase.assertEquals( + """ + SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers + INNER JOIN ( + SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags INNER JOIN event_tags as event_tagsIn1 ON event_tagsIn1.event_header_row_id = event_tags.event_header_row_id AND event_tagsIn1.created_at = event_tags.created_at WHERE (event_tags.tag_hash = "-4551135004136952885") AND (event_tagsIn1.tag_hash = "-6379614208644810021") AND (event_tags.kind = "1") ORDER BY event_tags.created_at DESC LIMIT 30 + ) AS filtered + ON event_headers.row_id = filtered.row_id + ORDER BY $orderBy + ├── CO-ROUTINE filtered + │ ├── SEARCH event_tags USING INDEX query_by_tags_hash_kind (tag_hash=? AND kind=?) + │ ├── SEARCH event_tagsIn1 USING INDEX query_by_tags_hash (tag_hash=? AND created_at=?) + │ └── USE TEMP B-TREE FOR DISTINCT + ├── SCAN filtered + ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) + └── USE TEMP B-TREE FOR ORDER BY + """.trimIndent(), + db.explain(filter), + ) + } else { + TestCase.assertEquals( + """ + SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers + INNER JOIN ( + SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags INNER JOIN event_tags as event_tagsIn1 ON event_tagsIn1.event_header_row_id = event_tags.event_header_row_id AND event_tagsIn1.created_at = event_tags.created_at WHERE (event_tags.tag_hash = "-4551135004136952885") AND (event_tagsIn1.tag_hash = "-6379614208644810021") AND (event_tags.kind = "1") ORDER BY event_tags.created_at DESC LIMIT 30 + ) AS filtered + ON event_headers.row_id = filtered.row_id + ORDER BY $orderBy + ├── CO-ROUTINE filtered + │ ├── SEARCH event_tags USING INDEX query_by_tags_hash_kind (tag_hash=? AND kind=?) + │ ├── SEARCH event_tagsIn1 USING INDEX fk_event_tags_header_id (event_header_row_id=?) + │ └── USE TEMP B-TREE FOR DISTINCT + ├── SCAN filtered + ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) + └── USE TEMP B-TREE FOR ORDER BY + """.trimIndent(), + db.explain(filter), + ) + } + } + + @Test + fun testIdQuery() = + forEachDB { db -> + val filter = Filter(ids = listOf(key1)) + if (db.indexStrategy.useAndIndexIdOnOrderBy) { + TestCase.assertEquals( + """ + SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers + WHERE id = "7c5eb72a4584fdaaeaa145b25c92ea9917704224951219dbd43acef9e91fb88d" + ORDER BY created_at DESC, id ASC + └── SEARCH event_headers USING INDEX event_headers_id (id=?) + """.trimIndent(), + db.explain(filter), + ) + } else { + TestCase.assertEquals( + """ + SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers + WHERE id = "7c5eb72a4584fdaaeaa145b25c92ea9917704224951219dbd43acef9e91fb88d" + ORDER BY created_at DESC + └── SEARCH event_headers USING INDEX event_headers_id (id=?) + """.trimIndent(), + db.explain(filter), + ) + } + } + + @Test + fun testAuthors() = + forEachDB { db -> + val filter = Filter(authors = listOf(key1, key2), kinds = listOf(1, 30023), limit = 300) + if (db.indexStrategy.useAndIndexIdOnOrderBy) { + TestCase.assertEquals( + """ + SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers + WHERE (kind IN ("1", "30023")) AND (pubkey IN ("7c5eb72a4584fdaaeaa145b25c92ea9917704224951219dbd43acef9e91fb88d", "f3ac434d61bc0f491a814782ccfdf9c439dae1f0bde9097ad4a245f4c495cd14")) + ORDER BY created_at DESC, id ASC + LIMIT 300 + ├── SEARCH event_headers USING INDEX query_by_kind_pubkey_created (kind=? AND pubkey=?) + └── USE TEMP B-TREE FOR ORDER BY + """.trimIndent(), + db.explain(filter), + ) + } else { + TestCase.assertEquals( + """ + SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers + WHERE (kind IN ("1", "30023")) AND (pubkey IN ("7c5eb72a4584fdaaeaa145b25c92ea9917704224951219dbd43acef9e91fb88d", "f3ac434d61bc0f491a814782ccfdf9c439dae1f0bde9097ad4a245f4c495cd14")) + ORDER BY created_at DESC + LIMIT 300 + ├── SEARCH event_headers USING INDEX query_by_kind_pubkey_created (kind=? AND pubkey=?) + └── USE TEMP B-TREE FOR ORDER BY + """.trimIndent(), + db.explain(filter), + ) + } + } + + @Test + fun testAuthorsAndSearch() = + forEachDB { db -> + val filter = Filter(authors = listOf(key1, key2, key3), search = "keywords") + if (db.indexStrategy.useAndIndexIdOnOrderBy) { + TestCase.assertEquals( + """ + SELECT event_headers.id, event_headers.pubkey, event_headers.created_at, event_headers.kind, event_headers.tags, event_headers.content, event_headers.sig FROM event_headers + INNER JOIN event_fts ON event_headers.row_id = event_fts.event_header_row_id + WHERE (event_fts MATCH "keywords") AND (event_headers.pubkey IN ("7c5eb72a4584fdaaeaa145b25c92ea9917704224951219dbd43acef9e91fb88d", "f3ac434d61bc0f491a814782ccfdf9c439dae1f0bde9097ad4a245f4c495cd14", "12ae0fd81c85e1e7d9ed096397dc3129849425fe6f8afce7213ebf38ddfc6ca9")) + ORDER BY event_headers.created_at DESC, event_headers.id ASC + ├── SCAN event_fts VIRTUAL TABLE INDEX 4: + ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) + └── USE TEMP B-TREE FOR ORDER BY + """.trimIndent(), + db.explain(filter), + ) + } else { + TestCase.assertEquals( + """ + SELECT event_headers.id, event_headers.pubkey, event_headers.created_at, event_headers.kind, event_headers.tags, event_headers.content, event_headers.sig FROM event_headers + INNER JOIN event_fts ON event_headers.row_id = event_fts.event_header_row_id + WHERE (event_fts MATCH "keywords") AND (event_headers.pubkey IN ("7c5eb72a4584fdaaeaa145b25c92ea9917704224951219dbd43acef9e91fb88d", "f3ac434d61bc0f491a814782ccfdf9c439dae1f0bde9097ad4a245f4c495cd14", "12ae0fd81c85e1e7d9ed096397dc3129849425fe6f8afce7213ebf38ddfc6ca9")) + ORDER BY event_headers.created_at DESC + ├── SCAN event_fts VIRTUAL TABLE INDEX 4: + ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) + └── USE TEMP B-TREE FOR ORDER BY + """.trimIndent(), + db.explain(filter), + ) + } + } + + @Test + fun testKindAndSearch() = + forEachDB { db -> + val filter = Filter(kinds = listOf(1, 1111, 10000), search = "keywords") + val orderBy = if (db.indexStrategy.useAndIndexIdOnOrderBy) "event_headers.created_at DESC, event_headers.id ASC" else "event_headers.created_at DESC" + TestCase.assertEquals( + """ + SELECT event_headers.id, event_headers.pubkey, event_headers.created_at, event_headers.kind, event_headers.tags, event_headers.content, event_headers.sig FROM event_headers + INNER JOIN event_fts ON event_headers.row_id = event_fts.event_header_row_id + WHERE (event_fts MATCH "keywords") AND (event_headers.kind IN ("1", "1111", "10000")) + ORDER BY $orderBy + ├── SCAN event_fts VIRTUAL TABLE INDEX 4: + ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) + └── USE TEMP B-TREE FOR ORDER BY + """.trimIndent(), + db.explain(filter), + ) + } + + @Test + fun testAllTag() = + forEachDB { db -> + val filter = Filter(tagsAll = mapOf("p" to listOf(key1, key2))) + val orderBy = if (db.indexStrategy.useAndIndexIdOnOrderBy) "created_at DESC, id ASC" else "created_at DESC" + if (db.indexStrategy.indexTagsByCreatedAtAlone) { + TestCase.assertEquals( + """ + SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers + INNER JOIN ( + SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags INNER JOIN event_tags as event_tagsAll0_1 ON event_tagsAll0_1.event_header_row_id = event_tags.event_header_row_id AND event_tagsAll0_1.created_at = event_tags.created_at WHERE (event_tags.tag_hash = "884286737453847614") AND (event_tagsAll0_1.tag_hash = "-4988851810256311323") + ) AS filtered + ON event_headers.row_id = filtered.row_id + ORDER BY $orderBy + ├── CO-ROUTINE filtered + │ ├── SEARCH event_tags USING INDEX query_by_tags_hash_kind (tag_hash=?) + │ ├── SEARCH event_tagsAll0_1 USING INDEX query_by_tags_hash (tag_hash=? AND created_at=?) + │ └── USE TEMP B-TREE FOR DISTINCT + ├── SCAN filtered + ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) + └── USE TEMP B-TREE FOR ORDER BY + """.trimIndent(), + db.explain(filter), + ) + } else { + TestCase.assertEquals( + """ + SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers + INNER JOIN ( + SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags INNER JOIN event_tags as event_tagsAll0_1 ON event_tagsAll0_1.event_header_row_id = event_tags.event_header_row_id AND event_tagsAll0_1.created_at = event_tags.created_at WHERE (event_tags.tag_hash = "884286737453847614") AND (event_tagsAll0_1.tag_hash = "-4988851810256311323") + ) AS filtered + ON event_headers.row_id = filtered.row_id + ORDER BY $orderBy + ├── CO-ROUTINE filtered + │ ├── SEARCH event_tags USING INDEX query_by_tags_hash_kind (tag_hash=?) + │ ├── SEARCH event_tagsAll0_1 USING INDEX fk_event_tags_header_id (event_header_row_id=?) + │ └── USE TEMP B-TREE FOR DISTINCT + ├── SCAN filtered + ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) + └── USE TEMP B-TREE FOR ORDER BY + """.trimIndent(), + db.explain(filter), + ) + } + } + + @Test + fun testReportLikeFilter() = + forEachDB { db -> + val filter = Filter( kinds = listOf(ContactListEvent.KIND), - limit = 30, - ), - ) - TestCase.assertEquals( - """ - SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers - WHERE kind = "3" - ORDER BY created_at DESC - LIMIT 30 - └── SEARCH event_headers USING INDEX query_by_kind_created (kind=?) - """.trimIndent(), - dbAllIndexes.explain(filter), - ) - } - - @Test - fun testKinds() { - val filter = - listOf( - Filter( - kinds = listOf(ContactListEvent.KIND), - limit = 30, - ), - Filter( - kinds = listOf(TextNoteEvent.KIND), - limit = 30, - ), - ) - TestCase.assertEquals( - """ - SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers - INNER JOIN ( - SELECT row_id FROM (SELECT event_headers.row_id as row_id FROM event_headers WHERE event_headers.kind = "3" ORDER BY event_headers.created_at DESC LIMIT 30) - UNION - SELECT row_id FROM (SELECT event_headers.row_id as row_id FROM event_headers WHERE event_headers.kind = "1" ORDER BY event_headers.created_at DESC LIMIT 30) - ) AS filtered - ON event_headers.row_id = filtered.row_id - ORDER BY created_at DESC - ├── CO-ROUTINE filtered - │ └── COMPOUND QUERY - │ ├── LEFT-MOST SUBQUERY - │ │ ├── CO-ROUTINE (subquery-1) - │ │ │ └── SEARCH event_headers USING COVERING INDEX query_by_kind_created (kind=?) - │ │ └── SCAN (subquery-1) - │ └── UNION USING TEMP B-TREE - │ ├── CO-ROUTINE (subquery-3) - │ │ └── SEARCH event_headers USING COVERING INDEX query_by_kind_created (kind=?) - │ └── SCAN (subquery-3) - ├── SCAN filtered - ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) - └── USE TEMP B-TREE FOR ORDER BY - """.trimIndent(), - dbAllIndexes.explain(filter), - ) - } - - @Test - fun testKindAndDTag() { - val filter = - listOf( - Filter( - kinds = listOf(ContactListEvent.KIND), - tags = mapOf("d" to listOf("")), - limit = 30, - ), - ) - TestCase.assertEquals( - """ - SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers - WHERE (kind = "3") AND (d_tag = "") - ORDER BY created_at DESC - LIMIT 30 - └── SEARCH event_headers USING INDEX query_by_kind_created (kind=?) - """.trimIndent(), - dbAllIndexes.explain(filter), - ) - } - - @Test - fun testFollowersOf() { - val filter = - listOf( - Filter( - kinds = listOf(ContactListEvent.KIND), - tags = mapOf("p" to listOf("460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c")), - limit = 30, - ), - ) - TestCase.assertEquals( - """ - SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers - INNER JOIN ( - SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags WHERE (event_tags.tag_hash = "-4551135004136952885") AND (event_tags.kind = "3") ORDER BY event_tags.created_at DESC LIMIT 30 - ) AS filtered - ON event_headers.row_id = filtered.row_id - ORDER BY created_at DESC - ├── CO-ROUTINE filtered - │ ├── SEARCH event_tags USING INDEX query_by_tags_hash_kind (tag_hash=? AND kind=?) - │ └── USE TEMP B-TREE FOR DISTINCT - ├── SCAN filtered - ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) - └── USE TEMP B-TREE FOR ORDER BY - """.trimIndent(), - dbAllIndexes.explain(filter), - ) - } - - @Test - fun testNotificationsOf() { - val filter = - listOf( - Filter( - tags = mapOf("p" to listOf("460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c")), - limit = 30, - ), - ) - TestCase.assertEquals( - """ - SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers - INNER JOIN ( - SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags WHERE event_tags.tag_hash = "-4551135004136952885" ORDER BY event_tags.created_at DESC LIMIT 30 - ) AS filtered - ON event_headers.row_id = filtered.row_id - ORDER BY created_at DESC - ├── CO-ROUTINE filtered - │ ├── SEARCH event_tags USING INDEX query_by_tags_hash (tag_hash=?) - │ └── USE TEMP B-TREE FOR DISTINCT - ├── SCAN filtered - ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) - └── USE TEMP B-TREE FOR ORDER BY - """.trimIndent(), - dbAllIndexes.explain(filter), - ) - } - - @Test - fun testTagsAndKinds() { - val filter = - listOf( - Filter( - kinds = listOf(ContactListEvent.KIND), - tags = mapOf("p" to listOf("460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c")), - limit = 30, - ), - ) - TestCase.assertEquals( - """ - SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers - INNER JOIN ( - SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags WHERE (event_tags.tag_hash = "-4551135004136952885") AND (event_tags.kind = "3") ORDER BY event_tags.created_at DESC LIMIT 30 - ) AS filtered - ON event_headers.row_id = filtered.row_id - ORDER BY created_at DESC - ├── CO-ROUTINE filtered - │ ├── SEARCH event_tags USING INDEX query_by_tags_hash_kind (tag_hash=? AND kind=?) - │ └── USE TEMP B-TREE FOR DISTINCT - ├── SCAN filtered - ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) - └── USE TEMP B-TREE FOR ORDER BY - """.trimIndent(), - dbAllIndexes.explain(filter), - ) - } - - @Test - fun testTagsAndAuthors() { - val filter = - listOf( - Filter( - authors = listOf(key1), - tags = mapOf("p" to listOf("460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c")), - limit = 30, - ), - ) - TestCase.assertEquals( - """ - SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers - INNER JOIN ( - SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags WHERE (event_tags.tag_hash = "-4551135004136952885") AND (event_tags.pubkey_hash = "1730514094536529999") ORDER BY event_tags.created_at DESC LIMIT 30 - ) AS filtered - ON event_headers.row_id = filtered.row_id - ORDER BY created_at DESC - ├── CO-ROUTINE filtered - │ ├── SEARCH event_tags USING INDEX query_by_tags_hash (tag_hash=?) - │ └── USE TEMP B-TREE FOR DISTINCT - ├── SCAN filtered - ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) - └── USE TEMP B-TREE FOR ORDER BY - """.trimIndent(), - dbAllIndexes.explain(filter), - ) - } - - @Test - fun testTwoTags() { - val filter = - listOf( - Filter( - kinds = listOf(1), + authors = listOf("460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c"), tags = mapOf( "p" to listOf("460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c"), - "t" to listOf("hashtag"), ), - limit = 30, - ), + limit = 500, + ) + val orderBy = if (db.indexStrategy.useAndIndexIdOnOrderBy) "created_at DESC, id ASC" else "created_at DESC" + if (db.indexStrategy.indexTagsWithKindAndPubkey) { + assertEquals( + """ + SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers + INNER JOIN ( + SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags WHERE (event_tags.tag_hash = "-4551135004136952885") AND (event_tags.kind = "3") AND (event_tags.pubkey_hash = "5446767199141196776") ORDER BY event_tags.created_at DESC LIMIT 500 + ) AS filtered + ON event_headers.row_id = filtered.row_id + ORDER BY $orderBy + ├── CO-ROUTINE filtered + │ ├── SEARCH event_tags USING INDEX query_by_tags_hash_kind_pubkey (tag_hash=? AND kind=? AND pubkey_hash=?) + │ └── USE TEMP B-TREE FOR DISTINCT + ├── SCAN filtered + ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) + └── USE TEMP B-TREE FOR ORDER BY + """.trimIndent(), + db.explain(filter), + ) + } else { + assertEquals( + """ + SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers + INNER JOIN ( + SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags WHERE (event_tags.tag_hash = "-4551135004136952885") AND (event_tags.kind = "3") AND (event_tags.pubkey_hash = "5446767199141196776") ORDER BY event_tags.created_at DESC LIMIT 500 + ) AS filtered + ON event_headers.row_id = filtered.row_id + ORDER BY $orderBy + ├── CO-ROUTINE filtered + │ ├── SEARCH event_tags USING INDEX query_by_tags_hash_kind (tag_hash=? AND kind=?) + │ └── USE TEMP B-TREE FOR DISTINCT + ├── SCAN filtered + ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) + └── USE TEMP B-TREE FOR ORDER BY + """.trimIndent(), + db.explain(filter), + ) + } + } + + @Test + fun testFollowersSinceNov2025() = + forEachDB { db -> + val filter = + Filter( + kinds = listOf(ContactListEvent.KIND), + tags = + mapOf( + "p" to listOf("460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c"), + ), + since = 1764553447, // Nov 2025 + ) + val orderBy = if (db.indexStrategy.useAndIndexIdOnOrderBy) "created_at DESC, id ASC" else "created_at DESC" + assertEquals( + """ + SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers + INNER JOIN ( + SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags WHERE (event_tags.tag_hash = "-4551135004136952885") AND (event_tags.kind = "3") AND (event_tags.created_at >= "1764553447") + ) AS filtered + ON event_headers.row_id = filtered.row_id + ORDER BY $orderBy + ├── CO-ROUTINE filtered + │ ├── SEARCH event_tags USING INDEX query_by_tags_hash_kind (tag_hash=? AND kind=? AND created_at>?) + │ └── USE TEMP B-TREE FOR DISTINCT + ├── SCAN filtered + ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) + └── USE TEMP B-TREE FOR ORDER BY + """.trimIndent(), + db.explain(filter), ) - TestCase.assertEquals( - """ - SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers - INNER JOIN ( - SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags INNER JOIN event_tags as event_tagsIn1 ON event_tagsIn1.event_header_row_id = event_tags.event_header_row_id AND event_tagsIn1.created_at = event_tags.created_at WHERE (event_tags.tag_hash = "-4551135004136952885") AND (event_tagsIn1.tag_hash = "-6379614208644810021") AND (event_tags.kind = "1") ORDER BY event_tags.created_at DESC LIMIT 30 - ) AS filtered - ON event_headers.row_id = filtered.row_id - ORDER BY created_at DESC - ├── CO-ROUTINE filtered - │ ├── SEARCH event_tags USING INDEX query_by_tags_hash_kind (tag_hash=? AND kind=?) - │ ├── SEARCH event_tagsIn1 USING INDEX query_by_tags_hash (tag_hash=? AND created_at=?) - │ └── USE TEMP B-TREE FOR DISTINCT - ├── SCAN filtered - ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) - └── USE TEMP B-TREE FOR ORDER BY - """.trimIndent(), - dbAllIndexes.explain(filter), - ) - } + } @Test - fun testIdQuery() { - val filter = Filter(ids = listOf(key1)) - TestCase.assertEquals( - """ - SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers - WHERE id = "7c5eb72a4584fdaaeaa145b25c92ea9917704224951219dbd43acef9e91fb88d" - ORDER BY created_at DESC - └── SEARCH event_headers USING INDEX event_headers_id (id=?) - """.trimIndent(), - dbAllIndexes.explain(filter), - ) - } - - @Test - fun testAuthors() { - val filter = Filter(authors = listOf(key1, key2), kinds = listOf(1, 30023), limit = 300) - TestCase.assertEquals( - """ - SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers - WHERE (kind IN ("1", "30023")) AND (pubkey IN ("7c5eb72a4584fdaaeaa145b25c92ea9917704224951219dbd43acef9e91fb88d", "f3ac434d61bc0f491a814782ccfdf9c439dae1f0bde9097ad4a245f4c495cd14")) - ORDER BY created_at DESC - LIMIT 300 - ├── SEARCH event_headers USING INDEX query_by_kind_pubkey_created (kind=? AND pubkey=?) - └── USE TEMP B-TREE FOR ORDER BY - """.trimIndent(), - dbAllIndexes.explain(filter), - ) - } - - @Test - fun testAuthorsAndSearch() { - val filter = Filter(authors = listOf(key1, key2, key3), search = "keywords") - println(dbAllIndexes.explain(filter)) - TestCase.assertEquals( - """ - SELECT event_headers.id, event_headers.pubkey, event_headers.created_at, event_headers.kind, event_headers.tags, event_headers.content, event_headers.sig FROM event_headers - INNER JOIN event_fts ON event_headers.row_id = event_fts.event_header_row_id - WHERE (event_fts MATCH "keywords") AND (event_headers.pubkey IN ("7c5eb72a4584fdaaeaa145b25c92ea9917704224951219dbd43acef9e91fb88d", "f3ac434d61bc0f491a814782ccfdf9c439dae1f0bde9097ad4a245f4c495cd14", "12ae0fd81c85e1e7d9ed096397dc3129849425fe6f8afce7213ebf38ddfc6ca9")) - ORDER BY event_headers.created_at DESC - ├── SCAN event_fts VIRTUAL TABLE INDEX 4: - ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) - └── USE TEMP B-TREE FOR ORDER BY - """.trimIndent(), - dbAllIndexes.explain(filter), - ) - } - - @Test - fun testKindAndSearch() { - val filter = Filter(kinds = listOf(1, 1111, 10000), search = "keywords") - println(dbAllIndexes.explain(filter)) - TestCase.assertEquals( - """ - SELECT event_headers.id, event_headers.pubkey, event_headers.created_at, event_headers.kind, event_headers.tags, event_headers.content, event_headers.sig FROM event_headers - INNER JOIN event_fts ON event_headers.row_id = event_fts.event_header_row_id - WHERE (event_fts MATCH "keywords") AND (event_headers.kind IN ("1", "1111", "10000")) - ORDER BY event_headers.created_at DESC - ├── SCAN event_fts VIRTUAL TABLE INDEX 4: - ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) - └── USE TEMP B-TREE FOR ORDER BY - """.trimIndent(), - dbAllIndexes.explain(filter), - ) - } - - @Test - fun testAllTag() { - val filter = Filter(tagsAll = mapOf("p" to listOf(key1, key2))) - TestCase.assertEquals( - """ - SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers - INNER JOIN ( - SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags INNER JOIN event_tags as event_tagsAll0_1 ON event_tagsAll0_1.event_header_row_id = event_tags.event_header_row_id AND event_tagsAll0_1.created_at = event_tags.created_at WHERE (event_tags.tag_hash = "884286737453847614") AND (event_tagsAll0_1.tag_hash = "-4988851810256311323") - ) AS filtered - ON event_headers.row_id = filtered.row_id - ORDER BY created_at DESC - ├── CO-ROUTINE filtered - │ ├── SEARCH event_tags USING INDEX query_by_tags_hash_kind (tag_hash=?) - │ ├── SEARCH event_tagsAll0_1 USING INDEX query_by_tags_hash (tag_hash=? AND created_at=?) - │ └── USE TEMP B-TREE FOR DISTINCT - ├── SCAN filtered - ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) - └── USE TEMP B-TREE FOR ORDER BY - """.trimIndent(), - dbAllIndexes.explain(filter), - ) - } - - @Test - fun testReportLikeFilter() { - val filter = - Filter( - kinds = listOf(ContactListEvent.KIND), - authors = listOf("460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c"), - tags = - mapOf( - "p" to listOf("460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c"), - ), - limit = 500, + fun testAllAddressablesOfAKindDownload() = + forEachDB { db -> + val filter = + Filter( + kinds = listOf(DraftWrapEvent.KIND), + authors = listOf("460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c"), + since = 1764553447, // Nov 2025 + ) + val orderBy = if (db.indexStrategy.useAndIndexIdOnOrderBy) "created_at DESC, id ASC" else "created_at DESC" + assertEquals( + """ + SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers + WHERE (kind = "31234") AND (pubkey = "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c") AND (created_at >= "1764553447") + ORDER BY $orderBy + └── SEARCH event_headers USING INDEX query_by_kind_pubkey_created (kind=? AND pubkey=? AND created_at>?) + """.trimIndent(), + db.explain(filter), ) - assertEquals( - """ - SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers - INNER JOIN ( - SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags WHERE (event_tags.tag_hash = "-4551135004136952885") AND (event_tags.kind = "3") AND (event_tags.pubkey_hash = "5446767199141196776") ORDER BY event_tags.created_at DESC LIMIT 500 - ) AS filtered - ON event_headers.row_id = filtered.row_id - ORDER BY created_at DESC - ├── CO-ROUTINE filtered - │ ├── SEARCH event_tags USING INDEX query_by_tags_hash_kind_pubkey (tag_hash=? AND kind=? AND pubkey_hash=?) - │ └── USE TEMP B-TREE FOR DISTINCT - ├── SCAN filtered - ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) - └── USE TEMP B-TREE FOR ORDER BY - """.trimIndent(), - dbAllIndexes.explain(filter), - ) - } + } @Test - fun testFollowersSinceNov2025() { - val filter = - Filter( - kinds = listOf(ContactListEvent.KIND), - tags = - mapOf( - "p" to listOf("460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c"), - ), - since = 1764553447, // Nov 2025 - ) - assertEquals( - """ - SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers - INNER JOIN ( - SELECT DISTINCT(event_tags.event_header_row_id) as row_id FROM event_tags WHERE (event_tags.tag_hash = "-4551135004136952885") AND (event_tags.kind = "3") AND (event_tags.created_at >= "1764553447") - ) AS filtered - ON event_headers.row_id = filtered.row_id - ORDER BY created_at DESC - ├── CO-ROUTINE filtered - │ ├── SEARCH event_tags USING INDEX query_by_tags_hash_kind (tag_hash=? AND kind=? AND created_at>?) - │ └── USE TEMP B-TREE FOR DISTINCT - ├── SCAN filtered - ├── SEARCH event_headers USING INTEGER PRIMARY KEY (rowid=?) - └── USE TEMP B-TREE FOR ORDER BY - """.trimIndent(), - dbAllIndexes.explain(filter), - ) - } + fun testReplaceablesOfMultipleKindsDownloadByDateLimit() = + forEachDB { db -> + val filter = + Filter( + kinds = listOf(MetadataEvent.KIND, SearchRelayListEvent.KIND, AdvertisedRelayListEvent.KIND), + authors = listOf("460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c"), + limit = 20, + since = 1764553447, // Nov 2025 + ) + if (db.indexStrategy.useAndIndexIdOnOrderBy) { + assertEquals( + """ + SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers + WHERE (kind IN ("0", "10007", "10002")) AND (pubkey = "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c") AND (created_at >= "1764553447") + ORDER BY created_at DESC, id ASC + LIMIT 20 + ├── SEARCH event_headers USING INDEX query_by_kind_pubkey_created (kind=? AND pubkey=? AND created_at>?) + └── USE TEMP B-TREE FOR ORDER BY + """.trimIndent(), + db.explain(filter), + ) + } else { + assertEquals( + """ + SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers + WHERE (kind IN ("0", "10007", "10002")) AND (pubkey = "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c") AND (created_at >= "1764553447") + ORDER BY created_at DESC + LIMIT 20 + ├── SEARCH event_headers USING INDEX query_by_kind_pubkey_created (kind=? AND pubkey=? AND created_at>?) + └── USE TEMP B-TREE FOR ORDER BY + """.trimIndent(), + db.explain(filter), + ) + } + } @Test - fun testAllAddressablesOfAKindDownload() { - val filter = - Filter( - kinds = listOf(DraftWrapEvent.KIND), - authors = listOf("460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c"), - since = 1764553447, // Nov 2025 - ) - assertEquals( - """ - SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers - WHERE (kind = "31234") AND (pubkey = "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c") AND (created_at >= "1764553447") - ORDER BY created_at DESC - └── SEARCH event_headers USING INDEX query_by_kind_pubkey_created (kind=? AND pubkey=? AND created_at>?) - """.trimIndent(), - dbAllIndexes.explain(filter), - ) - } + fun testReplaceablesOfMultipleKindsDownload() = + forEachDB { db -> + val filter = + Filter( + kinds = listOf(MetadataEvent.KIND, SearchRelayListEvent.KIND, AdvertisedRelayListEvent.KIND), + authors = listOf("460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c"), + ) + + if (db.indexStrategy.useAndIndexIdOnOrderBy) { + assertEquals( + """ + SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers + WHERE (kind IN ("0", "10007", "10002")) AND (pubkey = "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c") + ORDER BY created_at DESC, id ASC + ├── SEARCH event_headers USING INDEX query_by_kind_pubkey_created (kind=? AND pubkey=?) + └── USE TEMP B-TREE FOR ORDER BY + """.trimIndent(), + db.explain(filter), + ) + } else { + assertEquals( + """ + SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers + WHERE (kind IN ("0", "10007", "10002")) AND (pubkey = "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c") + ORDER BY created_at DESC + ├── SEARCH event_headers USING INDEX query_by_kind_pubkey_created (kind=? AND pubkey=?) + └── USE TEMP B-TREE FOR ORDER BY + """.trimIndent(), + db.explain(filter), + ) + } + } @Test - fun testReplaceablesOfMultipleKindsDownloadByDateLimit() { - val filter = - Filter( - kinds = listOf(MetadataEvent.KIND, SearchRelayListEvent.KIND, AdvertisedRelayListEvent.KIND), - authors = listOf("460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c"), - limit = 20, - since = 1764553447, // Nov 2025 - ) - assertEquals( - """ - SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers - WHERE (kind IN ("0", "10007", "10002")) AND (pubkey = "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c") AND (created_at >= "1764553447") - ORDER BY created_at DESC - LIMIT 20 - ├── SEARCH event_headers USING INDEX query_by_kind_pubkey_created (kind=? AND pubkey=? AND created_at>?) - └── USE TEMP B-TREE FOR ORDER BY - """.trimIndent(), - dbAllIndexes.explain(filter), - ) - } + fun testContactCardDownloadFromTrustedKeys() = + forEachDB { db -> + val filter = + Filter( + kinds = listOf(ContactCardEvent.KIND), + authors = listOf("460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c"), + tags = + mapOf( + "d" to listOf("460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c"), + ), + since = 1764553447, // Nov 2025 + ) - @Test - fun testReplaceablesOfMultipleKindsDownload() { - val filter = - Filter( - kinds = listOf(MetadataEvent.KIND, SearchRelayListEvent.KIND, AdvertisedRelayListEvent.KIND), - authors = listOf("460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c"), - ) - - assertEquals( - """ - SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers - WHERE (kind IN ("0", "10007", "10002")) AND (pubkey = "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c") - ORDER BY created_at DESC - ├── SEARCH event_headers USING INDEX query_by_kind_pubkey_created (kind=? AND pubkey=?) - └── USE TEMP B-TREE FOR ORDER BY - """.trimIndent(), - dbAllIndexes.explain(filter), - ) - } - - @Test - fun testContactCardDownloadFromTrustedKeys() { - val filter = - Filter( - kinds = listOf(ContactCardEvent.KIND), - authors = listOf("460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c"), - tags = - mapOf( - "d" to listOf("460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c"), - ), - since = 1764553447, // Nov 2025 - ) - - assertEquals( - """ - SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers - WHERE (kind = "30382") AND (pubkey = "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c") AND (d_tag = "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c") AND (created_at >= "1764553447") AND ((kind >= 30000 AND kind < 40000)) - ORDER BY created_at DESC - ├── SEARCH event_headers USING INDEX addressable_idx (kind=? AND pubkey=? AND d_tag=?) - └── USE TEMP B-TREE FOR ORDER BY - """.trimIndent(), - dbAllIndexes.explain(filter), - ) - } + if (db.indexStrategy.useAndIndexIdOnOrderBy) { + assertEquals( + """ + SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers + WHERE (kind = "30382") AND (pubkey = "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c") AND (d_tag = "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c") AND (created_at >= "1764553447") AND ((kind >= 30000 AND kind < 40000)) + ORDER BY created_at DESC, id ASC + ├── SEARCH event_headers USING INDEX addressable_idx (kind=? AND pubkey=? AND d_tag=?) + └── USE TEMP B-TREE FOR ORDER BY + """.trimIndent(), + db.explain(filter), + ) + } else { + assertEquals( + """ + SELECT id, pubkey, created_at, kind, tags, content, sig FROM event_headers + WHERE (kind = "30382") AND (pubkey = "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c") AND (d_tag = "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c") AND (created_at >= "1764553447") AND ((kind >= 30000 AND kind < 40000)) + ORDER BY created_at DESC + ├── SEARCH event_headers USING INDEX addressable_idx (kind=? AND pubkey=? AND d_tag=?) + └── USE TEMP B-TREE FOR ORDER BY + """.trimIndent(), + db.explain(filter), + ) + } + } } diff --git a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/DeletionRequestModule.kt b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/DeletionRequestModule.kt index deb4a061d..6905889e6 100644 --- a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/DeletionRequestModule.kt +++ b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/DeletionRequestModule.kt @@ -30,32 +30,45 @@ import com.vitorpamplona.quartz.nip09Deletions.DeletionEvent class DeletionRequestModule( val hasher: (db: SQLiteDatabase) -> TagNameValueHasher, + val indexStrategy: IndexingStrategy = DefaultIndexingStrategy(), ) : IModule { + fun rejectDeletedEventsSQLTemplate(): String = + if (indexStrategy.indexTagsWithKindAndPubkey) { + """ + |SELECT 1 FROM event_tags + |WHERE + | event_tags.tag_hash IN (NEW.etag_hash, NEW.atag_hash) AND + | event_tags.kind = 5 AND + | event_tags.pubkey_hash = NEW.pubkey_owner_hash AND + | event_tags.created_at >= NEW.created_at + """.trimMargin() + } else { + """ + |SELECT 1 FROM event_tags + |WHERE + | event_tags.tag_hash IN (NEW.etag_hash, NEW.atag_hash) AND + | event_tags.kind = 5 AND + | event_tags.created_at >= NEW.created_at AND + | event_tags.pubkey_hash = NEW.pubkey_owner_hash + """.trimMargin() + } + /** * Creates a trigger to reject events that have been * deleted by ID or ATag including GiftWraps that * must be checked against the p-tag (pubkey_owner_hash) */ override fun create(db: SQLiteDatabase) { + val sql = rejectDeletedEventsSQLTemplate().replace("\n", "\n ") db.execSQL( """ CREATE TRIGGER reject_deleted_events BEFORE INSERT ON event_headers FOR EACH ROW BEGIN - -- Checks if this event hasn't already been deleted. If so, reject it. - - -- Highly optimized using hash + created_at (duplicated in tags) index: - ---- Expects tag_hash to be non-existant for new events (quick exit) - ---- Expects created-at >= event's to not exist (quick exit) SELECT RAISE(ABORT, 'blocked: a deletion event exists') WHERE EXISTS ( - SELECT 1 FROM event_tags - WHERE - event_tags.tag_hash IN (NEW.etag_hash, NEW.atag_hash) AND - event_tags.kind = 5 AND - event_tags.pubkey_hash = NEW.pubkey_owner_hash AND - event_tags.created_at >= NEW.created_at + $sql ); END; """.trimIndent(), diff --git a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/EventIndexesModule.kt b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/EventIndexesModule.kt index 4dbe73aa4..8aefa83e4 100644 --- a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/EventIndexesModule.kt +++ b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/EventIndexesModule.kt @@ -75,8 +75,9 @@ class EventIndexesModule( } // queries by limit (latest records), since, until (sync all) alone without any filter by kind.. rare - // serves as fall back for the lack of query_by_tags_hash index by default - db.execSQL("CREATE INDEX query_by_created_at_id ON event_headers ($orderBy)") + if (indexStrategy.indexEventsByCreatedAtAlone) { + db.execSQL("CREATE INDEX query_by_created_at_id ON event_headers ($orderBy)") + } // queries by kind only, mostly used in Global Feeds when author is not important. db.execSQL("CREATE INDEX query_by_kind_created ON event_headers (kind, $orderBy)") @@ -87,10 +88,10 @@ class EventIndexesModule( // makes deletions on the event_header fast db.execSQL("CREATE INDEX fk_event_tags_header_id ON event_tags (event_header_row_id)") - // --------------------------------------------------------------- - // This are a very slow indexes (80% of the insert time goes here) - // --------------------------------------------------------------- - if (indexStrategy.indexTagQueriesWithoutKinds) { + // --------------------------------------------------------------------------- + // These next 3 are a very slow indexes (80% of the insert time goes here) + // --------------------------------------------------------------------------- + if (indexStrategy.indexTagsByCreatedAtAlone) { // First one is only needed if the user is searching by tags without a kind. db.execSQL("CREATE INDEX query_by_tags_hash ON event_tags (tag_hash, created_at DESC)") } @@ -98,8 +99,10 @@ class EventIndexesModule( // This is the default index for most clients: tags by specific kinds that are supported by the client. db.execSQL("CREATE INDEX query_by_tags_hash_kind ON event_tags (tag_hash, kind, created_at DESC)") - // this one is to allow search of tags by kind and author at the same time: DMs, reports, - db.execSQL("CREATE INDEX query_by_tags_hash_kind_pubkey ON event_tags (tag_hash, kind, pubkey_hash, created_at DESC)") + // this one is to allow search of tags by kind and author at the same time: NIP-04 DMs, reports, + if (indexStrategy.indexTagsWithKindAndPubkey) { + db.execSQL("CREATE INDEX query_by_tags_hash_kind_pubkey ON event_tags (tag_hash, kind, pubkey_hash, created_at DESC)") + } // Prevent updates to maintain immutability db.execSQL( diff --git a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/IndexingStrategy.kt b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/IndexingStrategy.kt index 1f5cf7745..a0a6ea1d4 100644 --- a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/IndexingStrategy.kt +++ b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/IndexingStrategy.kt @@ -23,7 +23,62 @@ package com.vitorpamplona.quartz.nip01Core.store.sqlite import com.vitorpamplona.quartz.nip01Core.core.Tag interface IndexingStrategy { - val indexTagQueriesWithoutKinds: Boolean + /** + * Activate this if you see too many Filters with just LIMIT, SINCE and + * UNTIL filled up. + * + * Clients never support all kinds, so this is usually + * only done with syncing services that must download ALL kinds from + * ALL authors. + * + * The index will make these queries significantly faster, but maybe speed + * is not a requirement on Sync services. The size of this index is + * considerable. + * + * Keep in mind that activating too many indexes increases the size of the + * DB so much that the indexes themselves won't fit in memory, requiring + * frequent reloadings of the index itself from disk. + */ + val indexEventsByCreatedAtAlone: Boolean + + /** + * Activate this if you see too many Tag-centric Filters without + * kind, pubkey or id. + * + * Clients never support all kinds, so this is usually + * only done in rare usecases where the client supports all + * kinds. + * + * The index will make these queries significantly faster, but maybe speed + * is not a requirement on such services. Because this is an index in + * event tags, it becomes QUITE BIG. + * + * Keep in mind that activating too many indexes increases the size of the + * DB so much that the indexes themselves won't fit in memory, requiring + * frequent reloadings of the index itself from disk. + */ + val indexTagsByCreatedAtAlone: Boolean + + /** + * Activate this if you see too many Tag-centric Filters without + * kind AND pubkey at the same time. + * + * This is a rarely used index (reports by your follows or + * NIP-04 DMs for instance) that becomes quite large without + * major gains. + * + * Keep in mind that activating too many indexes increases the size of the + * DB so much that the indexes themselves won't fit in memory, requiring + * frequent reloadings of the index itself from disk. + */ + val indexTagsWithKindAndPubkey: Boolean + + /** + * Activate this to make sure queries are always in order when + * the same created_at exists. This will impact performance and + * the size of indexes, but it provides results that are compliant + * with the Nostr Spec + */ val useAndIndexIdOnOrderBy: Boolean fun shouldIndex( @@ -36,7 +91,9 @@ interface IndexingStrategy { * By default, we index all tags that have a single letter name and some value */ class DefaultIndexingStrategy( - override val indexTagQueriesWithoutKinds: Boolean = false, + override val indexEventsByCreatedAtAlone: Boolean = false, + override val indexTagsByCreatedAtAlone: Boolean = false, + override val indexTagsWithKindAndPubkey: Boolean = false, override val useAndIndexIdOnOrderBy: Boolean = false, ) : IndexingStrategy { override fun shouldIndex( diff --git a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryBuilder.kt b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryBuilder.kt index ef4467b84..45e797cb4 100644 --- a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryBuilder.kt +++ b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryBuilder.kt @@ -655,7 +655,7 @@ class QueryBuilder( if (project) { append("\nORDER BY created_at DESC") if (indexStrategy.useAndIndexIdOnOrderBy) { - append(", event_headers.id ASC") + append(", id ASC") } } if (limit != null) { From 0d923b5caac0ecbbf941515d6a786c52892dcfd3 Mon Sep 17 00:00:00 2001 From: davotoula Date: Sun, 4 Jan 2026 12:19:00 +0100 Subject: [PATCH 38/63] optimise imports --- .../main/java/com/vitorpamplona/amethyst/service/relays/EOSE.kt | 1 - .../vitorpamplona/quartz/nip01Core/store/sqlite/QueryBuilder.kt | 2 -- .../kotlin/com/vitorpamplona/quartz/utils/SecureRandom.ios.kt | 1 - .../com/vitorpamplona/quartz/nip01Core/jackson/JacksonMapper.kt | 1 - 4 files changed, 5 deletions(-) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relays/EOSE.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relays/EOSE.kt index 0473c743b..5e7ed2ff6 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relays/EOSE.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relays/EOSE.kt @@ -22,7 +22,6 @@ package com.vitorpamplona.amethyst.service.relays import androidx.collection.LruCache import com.vitorpamplona.amethyst.model.User -import com.vitorpamplona.amethyst.service.relays.MutableTime import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl typealias SincePerRelayMap = MutableMap diff --git a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryBuilder.kt b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryBuilder.kt index 45e797cb4..d4ab144f6 100644 --- a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryBuilder.kt +++ b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nip01Core/store/sqlite/QueryBuilder.kt @@ -30,8 +30,6 @@ import com.vitorpamplona.quartz.nip01Core.core.isAddressable import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter import com.vitorpamplona.quartz.nip01Core.store.sqlite.sql.where import com.vitorpamplona.quartz.utils.EventFactory -import kotlin.collections.component1 -import kotlin.collections.component2 class QueryBuilder( val fts: FullTextSearchModule, diff --git a/quartz/src/iosMain/kotlin/com/vitorpamplona/quartz/utils/SecureRandom.ios.kt b/quartz/src/iosMain/kotlin/com/vitorpamplona/quartz/utils/SecureRandom.ios.kt index 26f0ed41d..cd27fd9ad 100644 --- a/quartz/src/iosMain/kotlin/com/vitorpamplona/quartz/utils/SecureRandom.ios.kt +++ b/quartz/src/iosMain/kotlin/com/vitorpamplona/quartz/utils/SecureRandom.ios.kt @@ -24,7 +24,6 @@ import kotlinx.cinterop.ExperimentalForeignApi import kotlinx.cinterop.refTo import platform.Security.SecRandomCopyBytes import platform.Security.kSecRandomDefault -import kotlin.random.Random.Default.nextBytes actual class SecureRandom { actual fun nextInt(): Int { diff --git a/quartz/src/jvmAndroid/kotlin/com/vitorpamplona/quartz/nip01Core/jackson/JacksonMapper.kt b/quartz/src/jvmAndroid/kotlin/com/vitorpamplona/quartz/nip01Core/jackson/JacksonMapper.kt index a6ca2615b..77c56012a 100644 --- a/quartz/src/jvmAndroid/kotlin/com/vitorpamplona/quartz/nip01Core/jackson/JacksonMapper.kt +++ b/quartz/src/jvmAndroid/kotlin/com/vitorpamplona/quartz/nip01Core/jackson/JacksonMapper.kt @@ -59,7 +59,6 @@ import com.vitorpamplona.quartz.nip47WalletConnect.jackson.ResponseDeserializer import com.vitorpamplona.quartz.nip59Giftwrap.rumors.Rumor import com.vitorpamplona.quartz.nip59Giftwrap.rumors.jackson.RumorDeserializer import com.vitorpamplona.quartz.nip59Giftwrap.rumors.jackson.RumorSerializer -import kotlinx.serialization.json.JsonNull.content import java.io.InputStream class JacksonMapper { From a4925de4a19208641c24114a80d7322b9d45ca39 Mon Sep 17 00:00:00 2001 From: davotoula Date: Sun, 4 Jan 2026 12:27:07 +0100 Subject: [PATCH 39/63] cleaner code --- .../java/com/vitorpamplona/amethyst/LocalPreferences.kt | 6 ++---- .../ui/screen/loggedIn/home/ShortNotePostViewModel.kt | 1 - 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/LocalPreferences.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/LocalPreferences.kt index d2678ca68..18916ef15 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/LocalPreferences.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/LocalPreferences.kt @@ -248,10 +248,8 @@ object LocalPreferences { withContext(Dispatchers.IO) { val prefsDir = File(prefsDirPath) prefsDir.list()?.forEach { - if (it.contains(npub)) { - if (!File(prefsDir, it).delete()) { - Log.w("LocalPreferences", "Failed to delete preference file: $it") - } + if (it.contains(npub) && !File(prefsDir, it).delete()) { + Log.w("LocalPreferences", "Failed to delete preference file: $it") } } } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/home/ShortNotePostViewModel.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/home/ShortNotePostViewModel.kt index 652cc425f..cd479b134 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/home/ShortNotePostViewModel.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/home/ShortNotePostViewModel.kt @@ -972,7 +972,6 @@ open class ShortNotePostViewModel : val uploadErrorTitle = stringRes(appContext, R.string.upload_error_title) val uploadVoiceNip95NotSupported = stringRes(appContext, R.string.upload_error_voice_message_nip95_not_supported) val uploadVoiceFailed = stringRes(appContext, R.string.upload_error_voice_message_failed) - val uploadVoiceUnexpected = stringRes(appContext, R.string.upload_error_voice_message_unexpected_state) val uploadVoiceExceptionMessage: (String) -> String = { detail -> stringRes(appContext, R.string.upload_error_voice_message_exception, detail) } From 59fb17563715b8b295a9f6100336d5fd3b898797 Mon Sep 17 00:00:00 2001 From: davotoula Date: Sun, 4 Jan 2026 12:32:08 +0100 Subject: [PATCH 40/63] refactor VoiceMessagePreview.kt --- .../ui/actions/uploads/VoiceMessagePreview.kt | 229 +++++++++++------- 1 file changed, 135 insertions(+), 94 deletions(-) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/uploads/VoiceMessagePreview.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/uploads/VoiceMessagePreview.kt index a601837be..7633a47d8 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/uploads/VoiceMessagePreview.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/uploads/VoiceMessagePreview.kt @@ -74,64 +74,23 @@ fun VoiceMessagePreview( var progress by remember { mutableFloatStateOf(0f) } var mediaPlayer by remember { mutableStateOf(null) } - // Initialize MediaPlayer - DisposableEffect(voiceMetadata.url, localFile) { - val player = createMediaPlayer(voiceMetadata.url, localFile) - player?.setOnCompletionListener { + ManageMediaPlayer( + voiceMetadata = voiceMetadata, + localFile = localFile, + onCompletion = { isPlaying = false progress = 0f - } - mediaPlayer = player + }, + onPlayerChanged = { mediaPlayer = it }, + onRelease = { isPlaying = false }, + ) - onDispose { - // Stop playback and clean up - try { - player?.stop() - } catch (e: IllegalStateException) { - // Player might already be stopped - Log.d("VoiceMessagePreview", "MediaPlayer stop failed (already stopped)", e) - } - player?.release() - mediaPlayer = null - isPlaying = false - } - } - - // Update progress while playing - LaunchedEffect(mediaPlayer, isPlaying) { - // Capture player reference to avoid reading volatile state repeatedly - val player = mediaPlayer - if (player != null && isPlaying) { - while (isActive) { - try { - if (player.isPlaying) { - val current = player.currentPosition.toFloat() - val duration = player.duration.toFloat() - // Validate values before calculating progress - val newProgress = - if (duration > 0 && current >= 0) { - (current / duration).coerceIn(0f, 1f) - } else { - 0f - } - // Only update if value is valid (not NaN or Infinity) - if (newProgress.isFinite()) { - progress = newProgress - } - } else { - // Player stopped, exit loop and let LaunchedEffect restart - break - } - } catch (e: IllegalStateException) { - // Player in invalid state, stop tracking - Log.w("VoiceMessagePreview", "MediaPlayer in invalid state during progress tracking", e) - isPlaying = false - break - } - delay(100) - } - } - } + TrackPlaybackProgress( + mediaPlayer = mediaPlayer, + isPlaying = isPlaying, + onProgressUpdate = { progress = it }, + onInvalidState = { isPlaying = false }, + ) Box( modifier = @@ -150,27 +109,13 @@ fun VoiceMessagePreview( // Play/Pause Button IconButton( onClick = { - val player = mediaPlayer - if (player != null) { - try { - if (isPlaying) { - player.pause() - isPlaying = false - } else { - // Validate progress before comparison - if (progress.isFinite() && progress >= 1f) { - player.seekTo(0) - progress = 0f - } - player.start() - isPlaying = true - } - } catch (e: IllegalStateException) { - // MediaPlayer in invalid state, ignore - Log.w("VoiceMessagePreview", "MediaPlayer operation failed in onClick handler", e) - isPlaying = false - } - } + handlePlayPauseClick( + mediaPlayer = mediaPlayer, + isPlaying = isPlaying, + progress = progress, + onProgressReset = { progress = 0f }, + onPlayingChanged = { isPlaying = it }, + ) }, modifier = Modifier.size(48.dp), ) { @@ -194,24 +139,11 @@ fun VoiceMessagePreview( waveformBrush = Brush.linearGradient(listOf(MaterialTheme.colorScheme.onSurfaceVariant, MaterialTheme.colorScheme.onSurfaceVariant)), progressBrush = Brush.linearGradient(listOf(MaterialTheme.colorScheme.primary, MaterialTheme.colorScheme.primary)), onProgressChange = { newProgress -> - // Validate incoming progress value - if (newProgress.isFinite() && newProgress >= 0f && newProgress <= 1f) { - val player = mediaPlayer - if (player != null) { - try { - val duration = player.duration - // Only seek if duration is valid - if (duration > 0) { - val newPosition = (newProgress * duration).toInt() - player.seekTo(newPosition) - progress = newProgress - } - } catch (e: IllegalStateException) { - // MediaPlayer in invalid state, ignore - Log.w("VoiceMessagePreview", "MediaPlayer seek failed in onProgressChange", e) - } - } - } + handleWaveformScrub( + newProgress = newProgress, + mediaPlayer = mediaPlayer, + onProgressChanged = { progress = it }, + ) }, ) @@ -240,6 +172,115 @@ fun VoiceMessagePreview( } } +@Composable +private fun ManageMediaPlayer( + voiceMetadata: AudioMeta, + localFile: File?, + onCompletion: () -> Unit, + onPlayerChanged: (MediaPlayer?) -> Unit, + onRelease: () -> Unit, +) { + DisposableEffect(voiceMetadata.url, localFile) { + val player = createMediaPlayer(voiceMetadata.url, localFile) + player?.setOnCompletionListener { onCompletion() } + onPlayerChanged(player) + + onDispose { + try { + player?.stop() + } catch (e: IllegalStateException) { + Log.d("VoiceMessagePreview", "MediaPlayer stop failed (already stopped)", e) + } + player?.release() + onPlayerChanged(null) + onRelease() + } + } +} + +@Composable +private fun TrackPlaybackProgress( + mediaPlayer: MediaPlayer?, + isPlaying: Boolean, + onProgressUpdate: (Float) -> Unit, + onInvalidState: () -> Unit, +) { + LaunchedEffect(mediaPlayer, isPlaying) { + val player = mediaPlayer ?: return@LaunchedEffect + if (!isPlaying) return@LaunchedEffect + + while (isActive) { + try { + if (!player.isPlaying) break + calculateProgress(player.currentPosition.toFloat(), player.duration.toFloat())?.let { onProgressUpdate(it) } + } catch (e: IllegalStateException) { + Log.w("VoiceMessagePreview", "MediaPlayer in invalid state during progress tracking", e) + onInvalidState() + break + } + delay(100) + } + } +} + +private fun calculateProgress( + current: Float, + duration: Float, +): Float? { + val progress = + if (duration > 0 && current >= 0) { + (current / duration).coerceIn(0f, 1f) + } else { + 0f + } + return progress.takeIf { it.isFinite() } +} + +private fun handlePlayPauseClick( + mediaPlayer: MediaPlayer?, + isPlaying: Boolean, + progress: Float, + onProgressReset: () -> Unit, + onPlayingChanged: (Boolean) -> Unit, +) { + val player = mediaPlayer ?: return + try { + if (isPlaying) { + player.pause() + onPlayingChanged(false) + return + } + if (progress.isFinite() && progress >= 1f) { + player.seekTo(0) + onProgressReset() + } + player.start() + onPlayingChanged(true) + } catch (e: IllegalStateException) { + Log.w("VoiceMessagePreview", "MediaPlayer operation failed in onClick handler", e) + onPlayingChanged(false) + } +} + +private fun handleWaveformScrub( + newProgress: Float, + mediaPlayer: MediaPlayer?, + onProgressChanged: (Float) -> Unit, +) { + if (!newProgress.isFinite() || newProgress < 0f || newProgress > 1f) return + val player = mediaPlayer ?: return + try { + val duration = player.duration + if (duration > 0) { + val newPosition = (newProgress * duration).toInt() + player.seekTo(newPosition) + onProgressChanged(newProgress) + } + } catch (e: IllegalStateException) { + Log.w("VoiceMessagePreview", "MediaPlayer seek failed in onProgressChange", e) + } +} + private fun createMediaPlayer( url: String, localFile: File?, From 69dd0b8e5e065cdba39974826eb9c53a19431251 Mon Sep 17 00:00:00 2001 From: Crowdin Bot Date: Sun, 4 Jan 2026 18:38:38 +0000 Subject: [PATCH 41/63] New Crowdin translations by GitHub Action --- amethyst/src/main/res/values-hu-rHU/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/amethyst/src/main/res/values-hu-rHU/strings.xml b/amethyst/src/main/res/values-hu-rHU/strings.xml index b64c49bbf..b889daa52 100644 --- a/amethyst/src/main/res/values-hu-rHU/strings.xml +++ b/amethyst/src/main/res/values-hu-rHU/strings.xml @@ -481,8 +481,8 @@ Adatvédelmi beállítások Tor és Orbot beállítása Kapcsolódás az Orbot beállításain keresztül - Beállítás - Tor beállítások + Módosítás + Tor Beállítások Kapcsolat bontása az Orbottal / Torral? Az Ön adatai azonnal átkerülnek a normál hálózatra Igen From eeafeeff1739f06c6ba10d3b04090cf9dae1042c Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Sun, 4 Jan 2026 14:40:45 -0500 Subject: [PATCH 42/63] Moves to new banner by Purple Painer --- .../res/drawable-xxxhdpi/profile_banner.jpg | Bin 186824 -> 542436 bytes .../drawable-xxxhdpi/profile_banner_old.jpg | Bin 0 -> 186824 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 amethyst/src/main/res/drawable-xxxhdpi/profile_banner_old.jpg diff --git a/amethyst/src/main/res/drawable-xxxhdpi/profile_banner.jpg b/amethyst/src/main/res/drawable-xxxhdpi/profile_banner.jpg index f0c93eb835a3c33919667b31b21819dc068d2097..126d9edf6dbbe009900f429fd0126adc67faa504 100644 GIT binary patch literal 542436 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�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�oyiq3fMBzI$}BcDBKXuD|M&D%fnd|4ewq_S(f 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

jc;w7pEHrk4a`IrkR(NSf%A4bL_+~^dG{J~ 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�>|rtdhQ3Yi#iL=!*Cb^*P7Mqtdnx{ak$C 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

87Uq+2{4i_7 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]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�UA@muKuwu;Tb4)t8ce?_UA=E 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 literal 186824 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 z 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 z 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 Date: Sun, 4 Jan 2026 16:38:06 -0500 Subject: [PATCH 43/63] Updates Vico --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index f2c9693c5..315e587d3 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -51,7 +51,7 @@ torAndroid = "0.4.8.21.1" translate = "17.0.3" unifiedpush = "3.0.10" urlDetector = "0.1.23" -vico-charts = "2.3.6" +vico-charts = "2.4.0" zelory = "3.0.1" zoomable = "2.9.0" zxing = "3.5.4" From fe1e0e46c3c04f702092245fb93f26d8c1994dd0 Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Sun, 4 Jan 2026 16:38:21 -0500 Subject: [PATCH 44/63] Fixes warnings on test case --- .../quartz/nip19Bech32/NIP19ParserTest.kt | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip19Bech32/NIP19ParserTest.kt b/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip19Bech32/NIP19ParserTest.kt index 58eb50846..072c6e5bc 100644 --- a/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip19Bech32/NIP19ParserTest.kt +++ b/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip19Bech32/NIP19ParserTest.kt @@ -106,9 +106,9 @@ class NIP19ParserTest { val actual = Nip19Parser.uriToRoute("nostr:nprofile1qqsyvrp9u6p0mfur9dfdru3d853tx9mdjuhkphxuxgfwmryja7zsvhqpzamhxue69uhhv6t5daezumn0wd68yvfwvdhk6tcpz9mhxue69uhkummnw3ezuamfdejj7qgwwaehxw309ahx7uewd3hkctcscpyug") assertNotNull(actual) - assertTrue(actual?.entity is NProfile) + assertTrue(actual.entity is NProfile) assertEquals("460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", actual.entity.hex) - assertEquals(NormalizedRelayUrl("wss://vitor.nostr1.com/"), actual.entity.relay?.first()) + assertEquals(NormalizedRelayUrl("wss://vitor.nostr1.com/"), actual.entity.relay.first()) } @Test() @@ -267,7 +267,7 @@ class NIP19ParserTest { "31337:27241bb702d145a975260cfedee6265936dcd939eaecb88ea0e4071752c30402:xx1xulrf7wdbdlbc31far", result.aTag(), ) - assertEquals(true, result.relay?.isEmpty()) + assertEquals(true, result.relay.isEmpty()) assertEquals("27241bb702d145a975260cfedee6265936dcd939eaecb88ea0e4071752c30402", result.author) assertEquals(31337, result.kind) } @@ -285,7 +285,7 @@ class NIP19ParserTest { "30023:46fcbe3065eaf1ae7811465924e48923363ff3f526bd6f73d7c184b16bd8ce4d:613f014d2911fb9df52e048aae70268c0d216790287b5814910e1e781e8e0509", result.aTag(), ) - assertEquals(true, result.relay?.isEmpty()) + assertEquals(true, result.relay.isEmpty()) assertEquals("46fcbe3065eaf1ae7811465924e48923363ff3f526bd6f73d7c184b16bd8ce4d", result.author) assertEquals(30023, result.kind) } @@ -303,7 +303,7 @@ class NIP19ParserTest { "30023:46fcbe3065eaf1ae7811465924e48923363ff3f526bd6f73d7c184b16bd8ce4d:1679509418", result.aTag(), ) - assertEquals(true, result.relay?.isEmpty()) + assertEquals(true, result.relay.isEmpty()) assertEquals("46fcbe3065eaf1ae7811465924e48923363ff3f526bd6f73d7c184b16bd8ce4d", result.author) assertEquals(30023, result.kind) } @@ -356,7 +356,7 @@ class NIP19ParserTest { assertEquals("b60ffa7256d3dd7543d830eb717ae50d05a6c32c5f791ed15b867c2bb0b954ac", result.hex) assertEquals( NormalizedRelayUrl("wss://nostr.mom/"), - result.relay?.get(0), + result.relay[0], ) assertEquals("f8ff11c7a7d3478355d3b4d174e5a473797a906ea4aa61aa9b6bc0652c1ea17a", result.author) assertEquals(1, result.kind) @@ -403,7 +403,7 @@ class NIP19ParserTest { assertNotNull(result) assertEquals("4300ec7fa2f98a276f033908349651620aa8e282b76030ab22abca63e85e07e6", result.hex) - assertEquals("wss://relay.damus.io/", result.relay.get(0)?.url) + assertEquals("wss://relay.damus.io/", result.relay[0].url) assertEquals("460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c", result.author) assertEquals(1, result.kind) } From a151bba3d0f3a9bddcb3feb80063ae196e9c9633 Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Sun, 4 Jan 2026 16:41:58 -0500 Subject: [PATCH 45/63] Improves stability for video ui --- .../vitorpamplona/quartz/nip94FileMetadata/tags/DimensionTag.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip94FileMetadata/tags/DimensionTag.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip94FileMetadata/tags/DimensionTag.kt index c5fc2131e..e03ac1d72 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip94FileMetadata/tags/DimensionTag.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip94FileMetadata/tags/DimensionTag.kt @@ -20,11 +20,13 @@ */ package com.vitorpamplona.quartz.nip94FileMetadata.tags +import androidx.compose.runtime.Stable import com.vitorpamplona.quartz.nip01Core.core.has import com.vitorpamplona.quartz.utils.ensure import kotlinx.serialization.Serializable @Serializable +@Stable class DimensionTag( val width: Int, val height: Int, From 2fc7e505a39a83a4d21b2ec96a0d95657fe00483 Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Mon, 5 Jan 2026 09:36:46 -0500 Subject: [PATCH 46/63] Update stability analiser --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 315e587d3..cbcc6baca 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -169,5 +169,5 @@ serialization = { id = 'org.jetbrains.kotlin.plugin.serialization', version.ref kotlinMultiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" } androidKotlinMultiplatformLibrary = { id = "com.android.kotlin.multiplatform.library", version.ref = "agp" } vanniktech-mavenPublish = { id = "com.vanniktech.maven.publish", version.ref = "mavenPublish" } -stability-analyzer = { id = "com.github.skydoves.compose.stability.analyzer", version = "0.6.1" } +stability-analyzer = { id = "com.github.skydoves.compose.stability.analyzer", version = "0.6.6" } composeMultiplatform = { id = "org.jetbrains.compose", version.ref = "composeMultiplatform" } From a9df6fcc61f13c60d11a8769e3f096567e31ecc5 Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Mon, 5 Jan 2026 13:38:24 -0500 Subject: [PATCH 47/63] Adds the default bookmark option to be inside the bookmark list screen --- .../vitorpamplona/amethyst/model/Account.kt | 9 ++ .../model/nip51Lists/BookmarkListState.kt | 25 ++++ .../amethyst/ui/navigation/AppNavigation.kt | 2 +- .../ui/navigation/drawer/DrawerContent.kt | 9 -- .../default}/BookmarkListScreen.kt | 8 +- .../default}/dal/BookmarkPrivateFeedFilter.kt | 2 +- .../dal/BookmarkPrivateFeedViewModel.kt | 2 +- .../default}/dal/BookmarkPublicFeedFilter.kt | 2 +- .../dal/BookmarkPublicFeedViewModel.kt | 2 +- .../display/BookmarkGroupScreen.kt | 4 +- .../list/ListOfBookmarkGroupsFeedView.kt | 108 ++++++++++----- .../list/ListOfBookmarkGroupsScreen.kt | 7 + .../list/NewBookmarkGroupCreationDialog.kt | 105 --------------- .../ArticleBookmarkListManagementScreen.kt | 125 ++++++++++------- .../PostBookmarkListManagementScreen.kt | 127 +++++++++++------- .../profile/bookmarks/BookmarkTabHeader.kt | 2 +- amethyst/src/main/res/values/strings.xml | 2 + .../bookmarkList/BookmarkListEvent.kt | 15 +++ 18 files changed, 307 insertions(+), 249 deletions(-) rename amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/{bookmarks => bookmarkgroups/default}/BookmarkListScreen.kt (94%) rename amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/{bookmarks => bookmarkgroups/default}/dal/BookmarkPrivateFeedFilter.kt (95%) rename amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/{bookmarks => bookmarkgroups/default}/dal/BookmarkPrivateFeedViewModel.kt (95%) rename amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/{bookmarks => bookmarkgroups/default}/dal/BookmarkPublicFeedFilter.kt (95%) rename amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/{bookmarks => bookmarkgroups/default}/dal/BookmarkPublicFeedViewModel.kt (95%) delete mode 100644 amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/list/NewBookmarkGroupCreationDialog.kt diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Account.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Account.kt index c38e80510..a3aed3278 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Account.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Account.kt @@ -1554,6 +1554,15 @@ class Account( } } + suspend fun removeBookmark(note: Note) { + if (!isWriteable() || note.isDraft()) return + + val event = bookmarkState.removeBookmark(note) + if (event != null) { + sendMyPublicAndPrivateOutbox(event) + } + } + suspend fun createAuthEvent( relay: NormalizedRelayUrl, challenge: String, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/nip51Lists/BookmarkListState.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/nip51Lists/BookmarkListState.kt index 6606229ec..19b2e1303 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/nip51Lists/BookmarkListState.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/nip51Lists/BookmarkListState.kt @@ -20,6 +20,7 @@ */ package com.vitorpamplona.amethyst.model.nip51Lists +import androidx.compose.runtime.Stable import com.vitorpamplona.amethyst.model.AddressableNote import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.Note @@ -40,7 +41,9 @@ import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onStart import kotlinx.coroutines.flow.stateIn +import java.lang.reflect.Modifier.isPrivate +@Stable class BookmarkListState( val signer: NostrSigner, val cache: LocalCache, @@ -274,4 +277,26 @@ class BookmarkListState( null } } + + suspend fun removeBookmark(note: Note): BookmarkListEvent? { + val bookmarkList = getBookmarkList() + + return if (bookmarkList != null) { + if (note is AddressableNote) { + BookmarkListEvent.remove( + earlierVersion = bookmarkList, + bookmarkIdTag = AddressBookmark(note.address, note.relayHintUrl()), + signer = signer, + ) + } else { + BookmarkListEvent.remove( + earlierVersion = bookmarkList, + bookmarkIdTag = EventBookmark(note.idHex, note.relayHintUrl()), + signer = signer, + ) + } + } else { + null + } + } } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppNavigation.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppNavigation.kt index 30d7e9a14..9266e299e 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppNavigation.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppNavigation.kt @@ -58,12 +58,12 @@ import com.vitorpamplona.amethyst.ui.note.nip22Comments.ReplyCommentPostScreen import com.vitorpamplona.amethyst.ui.screen.AccountStateViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountSwitcherAndLeftDrawerLayout import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel +import com.vitorpamplona.amethyst.ui.screen.loggedIn.bookmarkgroups.default.BookmarkListScreen import com.vitorpamplona.amethyst.ui.screen.loggedIn.bookmarkgroups.display.BookmarkGroupScreen import com.vitorpamplona.amethyst.ui.screen.loggedIn.bookmarkgroups.list.ListOfBookmarkGroupsScreen import com.vitorpamplona.amethyst.ui.screen.loggedIn.bookmarkgroups.list.metadata.BookmarkGroupMetadataScreen import com.vitorpamplona.amethyst.ui.screen.loggedIn.bookmarkgroups.membershipManagement.ArticleBookmarkListManagementScreen import com.vitorpamplona.amethyst.ui.screen.loggedIn.bookmarkgroups.membershipManagement.PostBookmarkListManagementScreen -import com.vitorpamplona.amethyst.ui.screen.loggedIn.bookmarks.BookmarkListScreen import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.privateDM.ChatroomByAuthorScreen import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.privateDM.ChatroomScreen import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.privateDM.send.NewGroupDMScreen diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/drawer/DrawerContent.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/drawer/DrawerContent.kt index fb16001a6..3ae138470 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/drawer/DrawerContent.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/drawer/DrawerContent.kt @@ -46,7 +46,6 @@ import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.Send import androidx.compose.material.icons.filled.AccountCircle import androidx.compose.material.icons.filled.Delete -import androidx.compose.material.icons.outlined.BookmarkBorder import androidx.compose.material.icons.outlined.CloudUpload import androidx.compose.material.icons.outlined.CollectionsBookmark import androidx.compose.material.icons.outlined.Drafts @@ -458,14 +457,6 @@ fun ListContent( NavigationRow( title = R.string.bookmarks, - icon = Icons.Outlined.BookmarkBorder, - tint = MaterialTheme.colorScheme.onBackground, - nav = nav, - route = Route.Bookmarks, - ) - - NavigationRow( - title = R.string.bookmark_lists, icon = Icons.Outlined.CollectionsBookmark, tint = MaterialTheme.colorScheme.onBackground, nav = nav, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarks/BookmarkListScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/default/BookmarkListScreen.kt similarity index 94% rename from amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarks/BookmarkListScreen.kt rename to amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/default/BookmarkListScreen.kt index ed958bead..111fc3876 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarks/BookmarkListScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/default/BookmarkListScreen.kt @@ -18,7 +18,7 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.amethyst.ui.screen.loggedIn.bookmarks +package com.vitorpamplona.amethyst.ui.screen.loggedIn.bookmarkgroups.default import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.layout.Column @@ -44,8 +44,8 @@ import com.vitorpamplona.amethyst.ui.navigation.navs.INav import com.vitorpamplona.amethyst.ui.navigation.topbars.TopBarWithBackButton import com.vitorpamplona.amethyst.ui.screen.RefresheableFeedView import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel -import com.vitorpamplona.amethyst.ui.screen.loggedIn.bookmarks.dal.BookmarkPrivateFeedViewModel -import com.vitorpamplona.amethyst.ui.screen.loggedIn.bookmarks.dal.BookmarkPublicFeedViewModel +import com.vitorpamplona.amethyst.ui.screen.loggedIn.bookmarkgroups.default.dal.BookmarkPrivateFeedViewModel +import com.vitorpamplona.amethyst.ui.screen.loggedIn.bookmarkgroups.default.dal.BookmarkPublicFeedViewModel import com.vitorpamplona.amethyst.ui.stringRes import com.vitorpamplona.amethyst.ui.theme.TabRowHeight import kotlinx.coroutines.launch @@ -93,7 +93,7 @@ private fun RenderBookmarkScreen( isInvertedLayout = false, topBar = { Column { - TopBarWithBackButton(stringRes(id = R.string.bookmarks), nav::popBack) + TopBarWithBackButton(stringRes(id = R.string.bookmarks_title), nav::popBack) TabRow( containerColor = Color.Transparent, contentColor = MaterialTheme.colorScheme.onBackground, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarks/dal/BookmarkPrivateFeedFilter.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/default/dal/BookmarkPrivateFeedFilter.kt similarity index 95% rename from amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarks/dal/BookmarkPrivateFeedFilter.kt rename to amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/default/dal/BookmarkPrivateFeedFilter.kt index 85cdc1d77..ad15db9ac 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarks/dal/BookmarkPrivateFeedFilter.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/default/dal/BookmarkPrivateFeedFilter.kt @@ -18,7 +18,7 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.amethyst.ui.screen.loggedIn.bookmarks.dal +package com.vitorpamplona.amethyst.ui.screen.loggedIn.bookmarkgroups.default.dal import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.model.Note diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarks/dal/BookmarkPrivateFeedViewModel.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/default/dal/BookmarkPrivateFeedViewModel.kt similarity index 95% rename from amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarks/dal/BookmarkPrivateFeedViewModel.kt rename to amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/default/dal/BookmarkPrivateFeedViewModel.kt index 3ddbd8e09..a0df51e0d 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarks/dal/BookmarkPrivateFeedViewModel.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/default/dal/BookmarkPrivateFeedViewModel.kt @@ -18,7 +18,7 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.amethyst.ui.screen.loggedIn.bookmarks.dal +package com.vitorpamplona.amethyst.ui.screen.loggedIn.bookmarkgroups.default.dal import androidx.compose.runtime.Stable import androidx.lifecycle.ViewModel diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarks/dal/BookmarkPublicFeedFilter.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/default/dal/BookmarkPublicFeedFilter.kt similarity index 95% rename from amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarks/dal/BookmarkPublicFeedFilter.kt rename to amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/default/dal/BookmarkPublicFeedFilter.kt index 34a3962fb..e6e1ab1d8 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarks/dal/BookmarkPublicFeedFilter.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/default/dal/BookmarkPublicFeedFilter.kt @@ -18,7 +18,7 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.amethyst.ui.screen.loggedIn.bookmarks.dal +package com.vitorpamplona.amethyst.ui.screen.loggedIn.bookmarkgroups.default.dal import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.model.Note diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarks/dal/BookmarkPublicFeedViewModel.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/default/dal/BookmarkPublicFeedViewModel.kt similarity index 95% rename from amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarks/dal/BookmarkPublicFeedViewModel.kt rename to amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/default/dal/BookmarkPublicFeedViewModel.kt index fb8ec6c8e..96b71053e 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarks/dal/BookmarkPublicFeedViewModel.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/default/dal/BookmarkPublicFeedViewModel.kt @@ -18,7 +18,7 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.amethyst.ui.screen.loggedIn.bookmarks.dal +package com.vitorpamplona.amethyst.ui.screen.loggedIn.bookmarkgroups.default.dal import androidx.compose.runtime.Stable import androidx.lifecycle.ViewModel diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/display/BookmarkGroupScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/display/BookmarkGroupScreen.kt index e4ca1fc88..b4d21b5b6 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/display/BookmarkGroupScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/display/BookmarkGroupScreen.kt @@ -42,7 +42,6 @@ import androidx.compose.material3.Scaffold import androidx.compose.material3.Tab import androidx.compose.material3.TabRow import androidx.compose.material3.Text -import androidx.compose.material3.TopAppBar import androidx.compose.material3.TopAppBarDefaults import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue @@ -59,6 +58,7 @@ import androidx.lifecycle.viewmodel.compose.viewModel import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.ui.components.ClickableBox import com.vitorpamplona.amethyst.ui.navigation.navs.INav +import com.vitorpamplona.amethyst.ui.navigation.topbars.ShorterTopAppBar import com.vitorpamplona.amethyst.ui.note.ArrowBackIcon import com.vitorpamplona.amethyst.ui.note.VerticalDotsIcon import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel @@ -118,7 +118,7 @@ fun BookmarkGroupScreenView( Scaffold( topBar = { Column { - TopAppBar( + ShorterTopAppBar( title = { TitleAndDescription(bookmarkGroupViewModel) }, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/list/ListOfBookmarkGroupsFeedView.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/list/ListOfBookmarkGroupsFeedView.kt index 9e603d023..dba0abacc 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/list/ListOfBookmarkGroupsFeedView.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/list/ListOfBookmarkGroupsFeedView.kt @@ -20,34 +20,43 @@ */ package com.vitorpamplona.amethyst.ui.screen.loggedIn.bookmarkgroups.list +import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.foundation.lazy.rememberLazyListState +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.outlined.BookmarkBorder import androidx.compose.material3.HorizontalDivider +import androidx.compose.material3.Icon +import androidx.compose.material3.ListItem import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.text.style.TextOverflow import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.vitorpamplona.amethyst.R +import com.vitorpamplona.amethyst.model.nip51Lists.BookmarkListState import com.vitorpamplona.amethyst.model.nip51Lists.labeledBookmarkLists.LabeledBookmarkList import com.vitorpamplona.amethyst.ui.screen.loggedIn.bookmarkgroups.BookmarkType import com.vitorpamplona.amethyst.ui.stringRes import com.vitorpamplona.amethyst.ui.theme.DividerThickness import com.vitorpamplona.amethyst.ui.theme.FeedPadding -import com.vitorpamplona.amethyst.ui.theme.Size40dp +import com.vitorpamplona.amethyst.ui.theme.Size40Modifier import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer import kotlinx.coroutines.flow.StateFlow @Composable fun ListOfBookmarkGroupsFeedView( + defaultBookmarks: BookmarkListState, groupListFeedSource: StateFlow>, + openDefaultBookmarks: () -> Unit, onOpenItem: (String, BookmarkType) -> Unit, onRenameItem: (targetBookmarkGroup: LabeledBookmarkList) -> Unit, onItemDescriptionChange: (bookmarkGroup: LabeledBookmarkList) -> Unit, @@ -56,40 +65,73 @@ fun ListOfBookmarkGroupsFeedView( ) { val bookmarkGroupFeedState by groupListFeedSource.collectAsStateWithLifecycle() - if (bookmarkGroupFeedState.isEmpty()) { - BookmarkGroupsFeedEmpty(message = stringRes(R.string.bookmark_list_feed_empty_msg)) - } else { - LazyColumn( - state = rememberLazyListState(), - contentPadding = FeedPadding, - ) { - itemsIndexed( - bookmarkGroupFeedState, - key = { _: Int, item: LabeledBookmarkList -> item.identifier }, - ) { _, groupItem -> - BookmarkGroupItem( - modifier = Modifier.fillMaxSize().animateItem(), - bookmarkList = groupItem, - onClick = { bookmarkType -> onOpenItem(groupItem.identifier, bookmarkType) }, - onRename = { onRenameItem(groupItem) }, - onDescriptionChange = { onItemDescriptionChange(groupItem) }, - onClone = { cloneName, cloneDescription -> onItemClone(groupItem, cloneName, cloneDescription) }, - onDelete = { onDeleteItem(groupItem) }, - ) - HorizontalDivider(thickness = DividerThickness) - } + LazyColumn( + state = rememberLazyListState(), + contentPadding = FeedPadding, + ) { + item { + DefaultBookmarkList(defaultBookmarks, openDefaultBookmarks) + HorizontalDivider(thickness = DividerThickness) + } + + itemsIndexed( + bookmarkGroupFeedState, + key = { _: Int, item: LabeledBookmarkList -> item.identifier }, + ) { _, groupItem -> + BookmarkGroupItem( + modifier = Modifier.fillMaxSize().animateItem(), + bookmarkList = groupItem, + onClick = { bookmarkType -> onOpenItem(groupItem.identifier, bookmarkType) }, + onRename = { onRenameItem(groupItem) }, + onDescriptionChange = { onItemDescriptionChange(groupItem) }, + onClone = { cloneName, cloneDescription -> onItemClone(groupItem, cloneName, cloneDescription) }, + onDelete = { onDeleteItem(groupItem) }, + ) + HorizontalDivider(thickness = DividerThickness) } } } @Composable -fun BookmarkGroupsFeedEmpty(message: String = stringRes(R.string.feed_is_empty)) { - Column( - Modifier.fillMaxSize().padding(horizontal = Size40dp), - horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.Center, - ) { - Text(message) - Spacer(modifier = StdVertSpacer) - } +fun DefaultBookmarkList( + defaultBookmarks: BookmarkListState, + openDefaultBookmarks: () -> Unit, +) { + val bookmarkState by defaultBookmarks.bookmarks.collectAsStateWithLifecycle() + + ListItem( + modifier = Modifier.clickable(onClick = openDefaultBookmarks), + headlineContent = { + Text(stringRes(R.string.bookmarks_title), maxLines = 1, overflow = TextOverflow.Ellipsis) + }, + supportingContent = { + Column( + modifier = Modifier.fillMaxWidth(), + ) { + Text( + stringRes(R.string.bookmarks_explainer), + overflow = TextOverflow.Ellipsis, + maxLines = 2, + ) + } + }, + leadingContent = { + Column( + verticalArrangement = Arrangement.Center, + horizontalAlignment = Alignment.CenterHorizontally, + ) { + Icon( + imageVector = Icons.Outlined.BookmarkBorder, + contentDescription = stringRes(R.string.bookmark_list_icon_label), + modifier = Size40Modifier, + ) + Spacer(StdVertSpacer) + BookmarkMembershipStatusAndNumberDisplay( + modifier = Modifier.align(Alignment.CenterHorizontally), + postBookmarksSize = bookmarkState.public.size + bookmarkState.private.size, + articleBookmarksSize = 0, + ) + } + }, + ) } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/list/ListOfBookmarkGroupsScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/list/ListOfBookmarkGroupsScreen.kt index 8903b1b48..6e5ad7581 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/list/ListOfBookmarkGroupsScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/list/ListOfBookmarkGroupsScreen.kt @@ -34,6 +34,7 @@ import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import com.vitorpamplona.amethyst.R +import com.vitorpamplona.amethyst.model.nip51Lists.BookmarkListState import com.vitorpamplona.amethyst.model.nip51Lists.labeledBookmarkLists.LabeledBookmarkList import com.vitorpamplona.amethyst.ui.navigation.navs.INav import com.vitorpamplona.amethyst.ui.navigation.routes.Route @@ -49,7 +50,9 @@ fun ListOfBookmarkGroupsScreen( nav: INav, ) { ListOfBookmarkGroupsFeed( + defaultBookmarks = accountViewModel.account.bookmarkState, listSource = accountViewModel.account.labeledBookmarkLists.listFeedFlow, + openDefaultBookmarks = { nav.nav(Route.Bookmarks) }, addBookmarkGroup = { nav.nav(Route.BookmarkGroupMetadataEdit()) }, openBookmarkGroup = { identifier, bookmarkType -> nav.nav(Route.BookmarkGroupView(identifier, bookmarkType)) @@ -84,7 +87,9 @@ fun ListOfBookmarkGroupsScreen( @Composable fun ListOfBookmarkGroupsFeed( + defaultBookmarks: BookmarkListState, listSource: StateFlow>, + openDefaultBookmarks: () -> Unit, addBookmarkGroup: () -> Unit, openBookmarkGroup: (identifier: String, bookmarkType: BookmarkType) -> Unit, renameBookmarkGroup: (bookmarkGroup: LabeledBookmarkList) -> Unit, @@ -109,7 +114,9 @@ fun ListOfBookmarkGroupsFeed( ).fillMaxHeight(), ) { ListOfBookmarkGroupsFeedView( + defaultBookmarks = defaultBookmarks, groupListFeedSource = listSource, + openDefaultBookmarks = openDefaultBookmarks, onOpenItem = openBookmarkGroup, onRenameItem = renameBookmarkGroup, onItemDescriptionChange = changeBookmarkGroupDescription, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/list/NewBookmarkGroupCreationDialog.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/list/NewBookmarkGroupCreationDialog.kt deleted file mode 100644 index 2f8680c6e..000000000 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/list/NewBookmarkGroupCreationDialog.kt +++ /dev/null @@ -1,105 +0,0 @@ -/** - * Copyright (c) 2025 Vitor Pamplona - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the - * Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -package com.vitorpamplona.amethyst.ui.screen.loggedIn.bookmarkgroups.list - -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer -import androidx.compose.material3.AlertDialog -import androidx.compose.material3.Button -import androidx.compose.material3.Text -import androidx.compose.material3.TextField -import androidx.compose.runtime.Composable -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.unit.dp -import com.vitorpamplona.amethyst.R -import com.vitorpamplona.amethyst.ui.stringRes -import com.vitorpamplona.amethyst.ui.theme.DoubleVertSpacer - -@Composable -fun NewBookmarkGroupCreationDialog( - modifier: Modifier = Modifier, - onDismiss: () -> Unit, - onCreateGroup: (name: String, description: String?) -> Unit, -) { - val newGroupName = remember { mutableStateOf("") } - val newGroupDescription = remember { mutableStateOf(null) } - - AlertDialog( - modifier = modifier, - onDismissRequest = onDismiss, - title = { - Row( - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.SpaceBetween, - ) { - Text( - text = "New Bookmark Group", - ) - } - }, - text = { - Column( - verticalArrangement = Arrangement.spacedBy(5.dp), - ) { - // For the new bookmark group name - TextField( - value = newGroupName.value, - onValueChange = { newGroupName.value = it }, - label = { - Text(text = "Group name") - }, - ) - Spacer(modifier = DoubleVertSpacer) - // For the group description - TextField( - value = - (if (newGroupDescription.value != null) newGroupDescription.value else "").toString(), - onValueChange = { newGroupDescription.value = it }, - label = { - Text(text = "Group description(optional)") - }, - ) - } - }, - confirmButton = { - Button( - onClick = { - onCreateGroup(newGroupName.value, newGroupDescription.value) - onDismiss() - }, - ) { - Text("Create Group") - } - }, - dismissButton = { - Button( - onClick = onDismiss, - ) { - Text(stringRes(R.string.cancel)) - } - }, - ) -} diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/membershipManagement/ArticleBookmarkListManagementScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/membershipManagement/ArticleBookmarkListManagementScreen.kt index ec36b977e..a5614fdf9 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/membershipManagement/ArticleBookmarkListManagementScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/membershipManagement/ArticleBookmarkListManagementScreen.kt @@ -44,7 +44,6 @@ import com.vitorpamplona.amethyst.ui.navigation.topbars.TopBarWithBackButton import com.vitorpamplona.amethyst.ui.note.LoadAddressableNote import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.bookmarkgroups.BookmarkType -import com.vitorpamplona.amethyst.ui.screen.loggedIn.bookmarkgroups.list.BookmarkGroupsFeedEmpty import com.vitorpamplona.amethyst.ui.screen.loggedIn.lists.list.NewListButton import com.vitorpamplona.amethyst.ui.stringRes import com.vitorpamplona.quartz.nip01Core.core.Address @@ -75,8 +74,6 @@ private fun ListManagementView( accountViewModel: AccountViewModel, nav: INav, ) { - val bookmarkGroups by accountViewModel.account.labeledBookmarkLists.listFeedFlow - .collectAsStateWithLifecycle() Scaffold( modifier = modifier, topBar = { @@ -95,48 +92,86 @@ private fun ListManagementView( ).consumeWindowInsets(contentPadding) .imePadding(), ) { - if (bookmarkGroups.isEmpty()) { - BookmarkGroupsFeedEmpty(message = stringRes(R.string.bookmark_list_feed_empty_msg)) - } else { - LazyColumn( - state = rememberLazyListState(), - modifier = Modifier.fillMaxWidth(), - ) { - itemsIndexed(items = bookmarkGroups, key = { _: Int, item: LabeledBookmarkList -> item.identifier }) { _, bookmarkList -> - val maybePublicBookmark = bookmarkList.publicArticleBookmarks.firstOrNull { it.address == note.address } - val maybePrivateBookmark = bookmarkList.privateArticleBookmarks.firstOrNull { it.address == note.address } - BookmarkGroupManagementItem( - modifier = Modifier.fillMaxWidth().animateItem(), - listTitle = bookmarkList.title, - isPublicMemberBookmark = maybePublicBookmark != null, - isPrivateMemberBookmark = maybePrivateBookmark != null, - totalPostBookmarkSize = bookmarkList.publicPostBookmarks.size + bookmarkList.privatePostBookmarks.size, - totalArticleBookmarkSize = bookmarkList.publicArticleBookmarks.size + bookmarkList.privateArticleBookmarks.size, - onClick = { nav.nav(Route.BookmarkGroupView(bookmarkList.identifier, BookmarkType.ArticleBookmark)) }, - onAddBookmarkToGroup = { shouldBePrivate -> - accountViewModel.launchSigner { - accountViewModel.account.labeledBookmarkLists.addBookmarkToList( - bookmark = AddressBookmark(address = note.address, relayHint = note.relayHintUrl()), - bookmarkListIdentifier = bookmarkList.identifier, - isBookmarkPrivate = shouldBePrivate, - account = accountViewModel.account, - ) - } - }, - onRemoveBookmarkFromGroup = { - accountViewModel.launchSigner { - accountViewModel.account.labeledBookmarkLists.removeBookmarkFromList( - bookmark = AddressBookmark(address = note.address), - bookmarkListIdentifier = bookmarkList.identifier, - isBookmarkPrivate = maybePrivateBookmark != null, - account = accountViewModel.account, - ) - } - }, - ) - } - } - } + ListManagementViewBody(note, accountViewModel, nav) + } + } +} + +@Composable +private fun ListManagementViewBody( + note: AddressableNote, + accountViewModel: AccountViewModel, + nav: INav, +) { + val bookmarkGroups by accountViewModel.account.labeledBookmarkLists.listFeedFlow + .collectAsStateWithLifecycle() + + val defaultBookmarks by accountViewModel.account.bookmarkState.bookmarks + .collectAsStateWithLifecycle() + + LazyColumn( + state = rememberLazyListState(), + modifier = Modifier.fillMaxWidth(), + ) { + item { + val maybePublicBookmark = defaultBookmarks.public.contains(note) + val maybePrivateBookmark = defaultBookmarks.private.contains(note) + + BookmarkGroupManagementItem( + modifier = Modifier.fillMaxWidth().animateItem(), + listTitle = stringRes(R.string.bookmarks_title), + isPublicMemberBookmark = maybePublicBookmark, + isPrivateMemberBookmark = maybePrivateBookmark, + totalPostBookmarkSize = defaultBookmarks.public.size + defaultBookmarks.private.size, + totalArticleBookmarkSize = 0, + onClick = { + nav.nav(Route.Bookmarks) + }, + onAddBookmarkToGroup = { shouldBePrivate -> + accountViewModel.launchSigner { + accountViewModel.account.addBookmark(note, shouldBePrivate) + } + }, + onRemoveBookmarkFromGroup = { + accountViewModel.launchSigner { + accountViewModel.account.removeBookmark(note) + } + }, + ) + } + + itemsIndexed(items = bookmarkGroups, key = { _: Int, item: LabeledBookmarkList -> item.identifier }) { _, bookmarkList -> + val maybePublicBookmark = bookmarkList.publicArticleBookmarks.firstOrNull { it.address == note.address } + val maybePrivateBookmark = bookmarkList.privateArticleBookmarks.firstOrNull { it.address == note.address } + BookmarkGroupManagementItem( + modifier = Modifier.fillMaxWidth().animateItem(), + listTitle = bookmarkList.title, + isPublicMemberBookmark = maybePublicBookmark != null, + isPrivateMemberBookmark = maybePrivateBookmark != null, + totalPostBookmarkSize = bookmarkList.publicPostBookmarks.size + bookmarkList.privatePostBookmarks.size, + totalArticleBookmarkSize = bookmarkList.publicArticleBookmarks.size + bookmarkList.privateArticleBookmarks.size, + onClick = { nav.nav(Route.BookmarkGroupView(bookmarkList.identifier, BookmarkType.ArticleBookmark)) }, + onAddBookmarkToGroup = { shouldBePrivate -> + accountViewModel.launchSigner { + accountViewModel.account.labeledBookmarkLists.addBookmarkToList( + bookmark = AddressBookmark(address = note.address, relayHint = note.relayHintUrl()), + bookmarkListIdentifier = bookmarkList.identifier, + isBookmarkPrivate = shouldBePrivate, + account = accountViewModel.account, + ) + } + }, + onRemoveBookmarkFromGroup = { + accountViewModel.launchSigner { + accountViewModel.account.labeledBookmarkLists.removeBookmarkFromList( + bookmark = AddressBookmark(address = note.address), + bookmarkListIdentifier = bookmarkList.identifier, + isBookmarkPrivate = maybePrivateBookmark != null, + account = accountViewModel.account, + ) + } + }, + ) } } } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/membershipManagement/PostBookmarkListManagementScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/membershipManagement/PostBookmarkListManagementScreen.kt index 14bb6478d..3ee8966aa 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/membershipManagement/PostBookmarkListManagementScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/membershipManagement/PostBookmarkListManagementScreen.kt @@ -44,7 +44,8 @@ import com.vitorpamplona.amethyst.ui.navigation.routes.Route import com.vitorpamplona.amethyst.ui.navigation.topbars.TopBarWithBackButton import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.bookmarkgroups.BookmarkType -import com.vitorpamplona.amethyst.ui.screen.loggedIn.bookmarkgroups.list.BookmarkGroupsFeedEmpty +import com.vitorpamplona.amethyst.ui.screen.loggedIn.bookmarkgroups.membershipManagement.ListManagementView +import com.vitorpamplona.amethyst.ui.screen.loggedIn.bookmarkgroups.membershipManagement.ListManagementViewBody import com.vitorpamplona.amethyst.ui.screen.loggedIn.lists.list.NewListButton import com.vitorpamplona.amethyst.ui.stringRes import com.vitorpamplona.quartz.nip51Lists.bookmarkList.tags.EventBookmark @@ -74,8 +75,6 @@ private fun ListManagementView( accountViewModel: AccountViewModel, nav: INav, ) { - val bookmarkGroups by accountViewModel.account.labeledBookmarkLists.listFeedFlow - .collectAsStateWithLifecycle() Scaffold( modifier = modifier, topBar = { @@ -94,48 +93,86 @@ private fun ListManagementView( ).consumeWindowInsets(contentPadding) .imePadding(), ) { - if (bookmarkGroups.isEmpty()) { - BookmarkGroupsFeedEmpty(message = stringRes(R.string.bookmark_list_feed_empty_msg)) - } else { - LazyColumn( - state = rememberLazyListState(), - modifier = Modifier.fillMaxWidth(), - ) { - itemsIndexed(items = bookmarkGroups, key = { _: Int, item: LabeledBookmarkList -> item.identifier }) { _, bookmarkList -> - val maybePublicBookmark = bookmarkList.publicPostBookmarks.firstOrNull { it.eventId == note.idHex } - val maybePrivateBookmark = bookmarkList.privatePostBookmarks.firstOrNull { it.eventId == note.idHex } - BookmarkGroupManagementItem( - modifier = Modifier.fillMaxWidth().animateItem(), - listTitle = bookmarkList.title, - isPublicMemberBookmark = maybePublicBookmark != null, - isPrivateMemberBookmark = maybePrivateBookmark != null, - totalPostBookmarkSize = bookmarkList.publicPostBookmarks.size + bookmarkList.privatePostBookmarks.size, - totalArticleBookmarkSize = bookmarkList.publicArticleBookmarks.size + bookmarkList.privateArticleBookmarks.size, - onClick = { nav.nav(Route.BookmarkGroupView(bookmarkList.identifier, BookmarkType.PostBookmark)) }, - onAddBookmarkToGroup = { shouldBePrivate -> - accountViewModel.launchSigner { - accountViewModel.account.labeledBookmarkLists.addBookmarkToList( - bookmark = EventBookmark(eventId = note.idHex, relay = note.relayHintUrl(), author = note.author?.pubkeyHex), - bookmarkListIdentifier = bookmarkList.identifier, - isBookmarkPrivate = shouldBePrivate, - account = accountViewModel.account, - ) - } - }, - onRemoveBookmarkFromGroup = { - accountViewModel.launchSigner { - accountViewModel.account.labeledBookmarkLists.removeBookmarkFromList( - bookmark = EventBookmark(eventId = note.idHex), - bookmarkListIdentifier = bookmarkList.identifier, - isBookmarkPrivate = maybePrivateBookmark != null, - account = accountViewModel.account, - ) - } - }, - ) - } - } - } + ListManagementViewBody(note, accountViewModel, nav) + } + } +} + +@Composable +private fun ListManagementViewBody( + note: Note, + accountViewModel: AccountViewModel, + nav: INav, +) { + val bookmarkGroups by accountViewModel.account.labeledBookmarkLists.listFeedFlow + .collectAsStateWithLifecycle() + + val defaultBookmarks by accountViewModel.account.bookmarkState.bookmarks + .collectAsStateWithLifecycle() + + LazyColumn( + state = rememberLazyListState(), + modifier = Modifier.fillMaxWidth(), + ) { + item { + val maybePublicBookmark = defaultBookmarks.public.contains(note) + val maybePrivateBookmark = defaultBookmarks.private.contains(note) + + BookmarkGroupManagementItem( + modifier = Modifier.fillMaxWidth().animateItem(), + listTitle = stringRes(R.string.bookmarks_title), + isPublicMemberBookmark = maybePublicBookmark, + isPrivateMemberBookmark = maybePrivateBookmark, + totalPostBookmarkSize = defaultBookmarks.public.size + defaultBookmarks.private.size, + totalArticleBookmarkSize = 0, + onClick = { + nav.nav(Route.Bookmarks) + }, + onAddBookmarkToGroup = { shouldBePrivate -> + accountViewModel.launchSigner { + accountViewModel.account.addBookmark(note, shouldBePrivate) + } + }, + onRemoveBookmarkFromGroup = { + accountViewModel.launchSigner { + accountViewModel.account.removeBookmark(note) + } + }, + ) + } + + itemsIndexed(items = bookmarkGroups, key = { _: Int, item: LabeledBookmarkList -> item.identifier }) { _, bookmarkList -> + val maybePublicBookmark = bookmarkList.publicPostBookmarks.firstOrNull { it.eventId == note.idHex } + val maybePrivateBookmark = bookmarkList.privatePostBookmarks.firstOrNull { it.eventId == note.idHex } + BookmarkGroupManagementItem( + modifier = Modifier.fillMaxWidth().animateItem(), + listTitle = bookmarkList.title, + isPublicMemberBookmark = maybePublicBookmark != null, + isPrivateMemberBookmark = maybePrivateBookmark != null, + totalPostBookmarkSize = bookmarkList.publicPostBookmarks.size + bookmarkList.privatePostBookmarks.size, + totalArticleBookmarkSize = bookmarkList.publicArticleBookmarks.size + bookmarkList.privateArticleBookmarks.size, + onClick = { nav.nav(Route.BookmarkGroupView(bookmarkList.identifier, BookmarkType.PostBookmark)) }, + onAddBookmarkToGroup = { shouldBePrivate -> + accountViewModel.launchSigner { + accountViewModel.account.labeledBookmarkLists.addBookmarkToList( + bookmark = EventBookmark(eventId = note.idHex, relay = note.relayHintUrl(), author = note.author?.pubkeyHex), + bookmarkListIdentifier = bookmarkList.identifier, + isBookmarkPrivate = shouldBePrivate, + account = accountViewModel.account, + ) + } + }, + onRemoveBookmarkFromGroup = { + accountViewModel.launchSigner { + accountViewModel.account.labeledBookmarkLists.removeBookmarkFromList( + bookmark = EventBookmark(eventId = note.idHex), + bookmarkListIdentifier = bookmarkList.identifier, + isBookmarkPrivate = maybePrivateBookmark != null, + account = accountViewModel.account, + ) + } + }, + ) } } } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/bookmarks/BookmarkTabHeader.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/bookmarks/BookmarkTabHeader.kt index 730d1dc3e..41a7cdca6 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/bookmarks/BookmarkTabHeader.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/bookmarks/BookmarkTabHeader.kt @@ -36,5 +36,5 @@ fun BookmarkTabHeader( ) { val userBookmarks by observeUserBookmarkCount(baseUser, accountViewModel) - Text(text = "$userBookmarks ${stringRes(R.string.bookmarks)}") + Text(text = "$userBookmarks ${stringRes(R.string.bookmarks_title)}") } diff --git a/amethyst/src/main/res/values/strings.xml b/amethyst/src/main/res/values/strings.xml index 7893b01aa..9542f59a9 100644 --- a/amethyst/src/main/res/values/strings.xml +++ b/amethyst/src/main/res/values/strings.xml @@ -391,6 +391,8 @@ Manual Zap Splits Bookmarks + Default Bookmarks + Your default Bookmarks that many clients support Drafts Private Bookmarks Public Bookmarks diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/bookmarkList/BookmarkListEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/bookmarkList/BookmarkListEvent.kt index 1118b2135..3c4e2ba5d 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/bookmarkList/BookmarkListEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/bookmarkList/BookmarkListEvent.kt @@ -148,6 +148,21 @@ class BookmarkListEvent( ) } + suspend fun remove( + earlierVersion: BookmarkListEvent, + bookmarkIdTag: BookmarkIdTag, + signer: NostrSigner, + createdAt: Long = TimeUtils.now(), + ): BookmarkListEvent { + val privateTags = earlierVersion.privateTags(signer) ?: throw SignerExceptions.UnauthorizedDecryptionException() + return resign( + privateTags = privateTags.remove(bookmarkIdTag.toTagIdOnly()), + tags = earlierVersion.tags.remove(bookmarkIdTag.toTagIdOnly()), + signer = signer, + createdAt = createdAt, + ) + } + suspend fun resign( tags: TagArray, privateTags: TagArray, From 1835c2238e3f67f951424a13caba729b4f139b64 Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Mon, 5 Jan 2026 16:01:39 -0500 Subject: [PATCH 48/63] removes unecessary log --- .../src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt index 28b05c3f2..3a89e5538 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt @@ -1106,7 +1106,6 @@ object LocalCache : ILocalCache { val new = consumeBaseReplaceable(event, relay, wasVerified) if (new) { - println("AABBCC New ContactCard about ${event.aboutUser()}") val about = checkGetOrCreateUser(event.aboutUser()) ?: return new about.cards().addCard(note) } From 2c4279621d27e407c03aad1394c0beeb4476f229 Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Mon, 5 Jan 2026 17:18:01 -0500 Subject: [PATCH 49/63] Makes the Kotlin Serialization lenient to avoid unnecessary crashes --- .../vitorpamplona/quartz/nip01Core/core/OptimizedJsonMapper.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/core/OptimizedJsonMapper.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/core/OptimizedJsonMapper.kt index 9e9b6de35..a671865a7 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/core/OptimizedJsonMapper.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/core/OptimizedJsonMapper.kt @@ -54,6 +54,7 @@ object JsonMapper { val jsonInstance = Json { ignoreUnknownKeys = true + isLenient = true } inline fun fromJson(json: String): T = jsonInstance.decodeFromString(json) From 69c53aca0657552c4e86d1d71f16f4e8ba98d2bb Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Mon, 5 Jan 2026 19:26:00 -0500 Subject: [PATCH 50/63] Improving error logs --- amethyst/src/main/java/com/vitorpamplona/amethyst/AppModules.kt | 2 +- .../main/java/com/vitorpamplona/amethyst/model/LocalCache.kt | 2 +- .../nip01Core/relay/client/single/basic/BasicRelayClient.kt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/AppModules.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/AppModules.kt index e62736ca8..8f28543b3 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/AppModules.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/AppModules.kt @@ -200,7 +200,7 @@ class AppModules( val relayStats = RelayStats(client) // Logs debug messages when needed - val detailedLogger = if (isDebug) RelayLogger(client, true, false) else null + val detailedLogger = if (isDebug) RelayLogger(client, false, false) else null val relayReqStats = if (isDebug) RelayReqStats(client) else null val logger = if (isDebug) RelaySpeedLogger(client) else null diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt index 3a89e5538..1b452063f 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt @@ -2889,7 +2889,7 @@ object LocalCache : ILocalCache { } } catch (e: Exception) { if (e is CancellationException) throw e - Log.w("LocalCache", "Cannot consume ${event.kind}", e) + Log.w("LocalCache", "Cannot consume ${event.toJson()} from ${relay?.url}", e) false } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/single/basic/BasicRelayClient.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/single/basic/BasicRelayClient.kt index 0d765370c..71e420f13 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/single/basic/BasicRelayClient.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/single/basic/BasicRelayClient.kt @@ -128,7 +128,7 @@ open class BasicRelayClient( } catch (e: Throwable) { if (e is CancellationException) throw e // doesn't expose parsing errors to lib users as errors - Log.e("BasicRelayClient", "Failure to parse message from Relay", e) + Log.e("BasicRelayClient", "Failure to parse message from Relay: $text", e) } } From 8a5e05c0acb8a0045fe42eb16ef84a44d60a5e71 Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Mon, 5 Jan 2026 19:26:24 -0500 Subject: [PATCH 51/63] Simple check to make sure events are valid. --- .../quartz/nip01Core/jackson/EventDeserializer.kt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/quartz/src/jvmAndroid/kotlin/com/vitorpamplona/quartz/nip01Core/jackson/EventDeserializer.kt b/quartz/src/jvmAndroid/kotlin/com/vitorpamplona/quartz/nip01Core/jackson/EventDeserializer.kt index 2dd3c09b1..7ea980703 100644 --- a/quartz/src/jvmAndroid/kotlin/com/vitorpamplona/quartz/nip01Core/jackson/EventDeserializer.kt +++ b/quartz/src/jvmAndroid/kotlin/com/vitorpamplona/quartz/nip01Core/jackson/EventDeserializer.kt @@ -63,6 +63,10 @@ class EventDeserializer : StdDeserializer(Event::class.java) { } } + if (pubKey.isEmpty()) { + throw IllegalArgumentException("Event not found") + } + return EventFactory.create(id, pubKey, createdAt, kind, tags, content, sig) } } From 40f9622722e52f61585f3a3ddbc335c8fc099885 Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Mon, 5 Jan 2026 19:41:23 -0500 Subject: [PATCH 52/63] Checks kind size before throwing --- .../quartz/nip01Core/core/AddressSerializer.kt | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/core/AddressSerializer.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/core/AddressSerializer.kt index ca60a06cd..23c9cf33d 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/core/AddressSerializer.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/core/AddressSerializer.kt @@ -44,7 +44,13 @@ class AddressSerializer { return try { val parts = addressId.split(":", limit = 3) if (parts.size > 2 && parts[1].length == 64 && Hex.isHex(parts[1])) { - Address(parts[0].toInt(), parts[1], parts.getOrNull(2) ?: "") + if (parts[0].length > 5) { + // invalid kind + Log.w("AddressableId", "Error parsing. invalid kind $addressId") + null + } else { + Address(parts[0].toInt(), parts[1], parts.getOrNull(2) ?: "") + } } else { if (addressId.startsWith("naddr1")) { val addr = Nip19Parser.uriToRoute(addressId)?.entity @@ -60,7 +66,7 @@ class AddressSerializer { } } } catch (t: Throwable) { - Log.e("AddressableId", "Error parsing: $addressId: ${t.message}", t) + Log.w("AddressableId", "Error parsing: $addressId: ${t.message}", t) null } } From 173a40394e94664d76ebb6561a92ad9f8500a1ba Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Tue, 6 Jan 2026 09:32:23 -0500 Subject: [PATCH 53/63] Smaller icon to avoid interfering with Trust scores --- .../main/java/com/vitorpamplona/amethyst/ui/theme/Theme.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/theme/Theme.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/theme/Theme.kt index 5f876fb25..56e05d901 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/theme/Theme.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/theme/Theme.kt @@ -215,13 +215,13 @@ val LightSelectedReactionBoxModifier = val DarkChannelNotePictureModifier = Modifier - .size(30.dp) + .size(25.dp) .clip(shape = CircleShape) .border(2.dp, DarkColorPalette.background, CircleShape) val LightChannelNotePictureModifier = Modifier - .size(30.dp) + .size(25.dp) .clip(shape = CircleShape) .border(2.dp, LightColorPalette.background, CircleShape) From fe0723889d42ba60c2845731788947837a067573 Mon Sep 17 00:00:00 2001 From: Crowdin Bot Date: Tue, 6 Jan 2026 14:34:17 +0000 Subject: [PATCH 54/63] New Crowdin translations by GitHub Action --- .../src/main/res/values-uz-rUZ/strings.xml | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/amethyst/src/main/res/values-uz-rUZ/strings.xml b/amethyst/src/main/res/values-uz-rUZ/strings.xml index cc4646375..7f89d981a 100644 --- a/amethyst/src/main/res/values-uz-rUZ/strings.xml +++ b/amethyst/src/main/res/values-uz-rUZ/strings.xml @@ -21,6 +21,7 @@ Noqonuniy xatti-harakat Boshqa sabab Ta’qib + Zo\'ravon Noma\'lum Relay belgisi Nomaʼlum muallif @@ -45,4 +46,26 @@ Sizda ommaviy kalit faol. Ommaviy kalitlar orqali faqat o‘qish mumkin. Xabar yozish uchun, maxfiy kalit bilan avtorizatsiyadan o‘ting Sizda ommaviy kalit faol. Ommaviy kalitlar orqali faqat o‘qish mumkin. Postni targ‘ib qilish uchun, maxfiy kalit bilan avtorizatsiyadan o‘ting Sizda ommaviy kalit faol. Ommaviy kalitlar orqali faqat o‘qish mumkin. Postga reaksiya qilish uchun, maxfiy kalit bilan avtorizatsiyadan o‘ting + Siz ommaviy kalitdan foydalanmoqdasiz va ommaviy kalitlar faqat o‘qish huquqiga ega. Obuna bo‘lish uchun shaxsiy kalit bilan tizimga kiring + Siz ommaviy kalitdan foydalanmoqdasiz va ommaviy kalitlar faqat o‘qish huquqiga ega. Yuklash uchun shaxsiy kalit bilan tizimga kiring + Siz ommaviy kalitdan foydalanmoqdasiz va ommaviy kalitlar faqat o‘qish huquqiga ega. Xabarlarni imzolash uchun shaxsiy kalit bilan tizimga kiring + Ruxsatsiz deshifrlash + Imzolovchi ushbu operatsiyani amalga oshirish uchun zarur boʻlgan shifrlashni ochishga ruxsat bermadi. Imzolovchi ilovangizda NIP-44 shifrlashni ochish funksiyasini yoqing va qaytadan urinib koʻring + Imzolovchi ilova topilmadi + Imzolovchi ilova oʻchirib tashlandimi? Imzolovchi oʻrnatilganligini va ushbu hisobga ega ekanligini tekshiring. Agar imzolovchi ilova oʻzgargan boʻlsa, tizimdan chiqing va qayta kiring. + Zeplar + Koʻrishlar soni + Targʻib qilish + Targ\'ib qilidi + Tahrirlangan + Tahrir № %1$s + Asl + Iqtibos qilish + Nusxa olish + Tahrir taklif qilish + Qo\'shish + "Kimga javob yozilmoqda: " + " va " + "bu kanalda: " + Profil banneri From d837fbb4c9bdf57f7b7e77a646f677c81c8845b2 Mon Sep 17 00:00:00 2001 From: davotoula Date: Tue, 6 Jan 2026 15:49:35 +0100 Subject: [PATCH 55/63] remove unused imports --- .../amethyst/model/nip51Lists/BookmarkListState.kt | 1 - .../membershipManagement/PostBookmarkListManagementScreen.kt | 2 -- 2 files changed, 3 deletions(-) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/nip51Lists/BookmarkListState.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/nip51Lists/BookmarkListState.kt index 19b2e1303..e97ab1585 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/nip51Lists/BookmarkListState.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/nip51Lists/BookmarkListState.kt @@ -41,7 +41,6 @@ import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onStart import kotlinx.coroutines.flow.stateIn -import java.lang.reflect.Modifier.isPrivate @Stable class BookmarkListState( diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/membershipManagement/PostBookmarkListManagementScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/membershipManagement/PostBookmarkListManagementScreen.kt index 3ee8966aa..e38ea0a9a 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/membershipManagement/PostBookmarkListManagementScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/bookmarkgroups/membershipManagement/PostBookmarkListManagementScreen.kt @@ -44,8 +44,6 @@ import com.vitorpamplona.amethyst.ui.navigation.routes.Route import com.vitorpamplona.amethyst.ui.navigation.topbars.TopBarWithBackButton import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.bookmarkgroups.BookmarkType -import com.vitorpamplona.amethyst.ui.screen.loggedIn.bookmarkgroups.membershipManagement.ListManagementView -import com.vitorpamplona.amethyst.ui.screen.loggedIn.bookmarkgroups.membershipManagement.ListManagementViewBody import com.vitorpamplona.amethyst.ui.screen.loggedIn.lists.list.NewListButton import com.vitorpamplona.amethyst.ui.stringRes import com.vitorpamplona.quartz.nip51Lists.bookmarkList.tags.EventBookmark From fd47391afeb1698600e264b94b5806677f90b811 Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Tue, 6 Jan 2026 10:08:29 -0500 Subject: [PATCH 56/63] Decreases the icon even further --- .../main/java/com/vitorpamplona/amethyst/ui/theme/Theme.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/theme/Theme.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/theme/Theme.kt index 56e05d901..a635810d9 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/theme/Theme.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/theme/Theme.kt @@ -215,13 +215,13 @@ val LightSelectedReactionBoxModifier = val DarkChannelNotePictureModifier = Modifier - .size(25.dp) + .size(20.dp) .clip(shape = CircleShape) .border(2.dp, DarkColorPalette.background, CircleShape) val LightChannelNotePictureModifier = Modifier - .size(25.dp) + .size(20.dp) .clip(shape = CircleShape) .border(2.dp, LightColorPalette.background, CircleShape) From e26fb949331c38e8af5a61e2653a3f091bb60124 Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Tue, 6 Jan 2026 17:38:47 -0500 Subject: [PATCH 57/63] Improvements on NIP-11 - Support for self, privacy_policy, terms_of_service, grasps - New UI for the Relay Information Screen - Improvements to the Debug Message - Compose-stable objects - Clickable elements for NIPs, external links, grasps, etc --- .../amethyst/model/AntiSpamFilter.kt | 4 +- .../amethyst/ui/note/NoteQuickActionMenu.kt | 8 + .../ui/note/ZapFormatterNoDecimals.kt | 6 + .../loggedIn/relays/RelayInformationScreen.kt | 1102 ++++++++++++----- amethyst/src/main/res/values/strings.xml | 45 +- .../amethyst/commons/util/TimeAgoFormatter.kt | 45 + .../nip01Core/relay/client/stats/RelayStat.kt | 50 +- .../relay/normalizer/NormalizedRelayUrl.kt | 3 + .../FlexibleIntListSerializer.kt | 14 +- .../nip11RelayInfo/Nip11RelayInformation.kt | 96 +- 10 files changed, 1008 insertions(+), 365 deletions(-) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/AntiSpamFilter.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/AntiSpamFilter.kt index 902a9015b..67b8afb51 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/AntiSpamFilter.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/AntiSpamFilter.kt @@ -95,7 +95,7 @@ class AntiSpamFilter { if (spammer.shouldHide() && relay != null) { Amethyst.instance.relayStats .get(relay) - .newSpam("$link1 $link2") + .newSpam(link1, link2) } flowSpam.tryEmit(AntiSpamState(this)) @@ -123,7 +123,7 @@ class AntiSpamFilter { if (spammer.shouldHide() && relay != null) { Amethyst.instance.relayStats .get(relay) - .newSpam("$link1 $link2") + .newSpam(link1, link2) } flowSpam.tryEmit(AntiSpamState(this)) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteQuickActionMenu.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteQuickActionMenu.kt index 070403e87..c1bc1c0a1 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteQuickActionMenu.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteQuickActionMenu.kt @@ -116,6 +116,14 @@ val njumpLink = { nip19BechAddress: String -> "https://njump.to/$nip19BechAddress" } +val nipLink = { nipNumber: String -> + "https://nostrhub.io/$nipNumber" +} + +val graspLink = { graspNumber: String -> + "https://gitworkshop.dev/danconwaydev.com/grasp/tree/master/$graspNumber.md" +} + val externalLinkForNote = { note: Note -> if (note is AddressableNote) { if (note.event?.bountyBaseReward() != null) { diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/ZapFormatterNoDecimals.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/ZapFormatterNoDecimals.kt index 2b33c9b50..e6b09d2ca 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/ZapFormatterNoDecimals.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/ZapFormatterNoDecimals.kt @@ -56,6 +56,12 @@ fun showAmountInteger(amount: BigDecimal?): String { } } +fun showAmountInteger(amount: Int?): String { + if (amount == null) return "0" + + return showAmountIntegerWithZero(BigDecimal.valueOf(amount.toLong())) +} + fun showAmountIntegerWithZero(amount: BigDecimal?): String { if (amount == null) return "0" if (amount.abs() < BigDecimal(0.01)) return "0" diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/relays/RelayInformationScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/relays/RelayInformationScreen.kt index ce9cc9466..5e4fc7b20 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/relays/RelayInformationScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/relays/RelayInformationScreen.kt @@ -20,65 +20,113 @@ */ package com.vitorpamplona.amethyst.ui.screen.loggedIn.relays +import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.ExperimentalLayoutApi import androidx.compose.foundation.layout.FlowRow +import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.consumeWindowInsets import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items +import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.text.selection.SelectionContainer +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.automirrored.filled.Article +import androidx.compose.material.icons.automirrored.filled.ContactSupport +import androidx.compose.material.icons.automirrored.filled.Label +import androidx.compose.material.icons.automirrored.filled.List +import androidx.compose.material.icons.automirrored.filled.Message +import androidx.compose.material.icons.filled.AttachMoney +import androidx.compose.material.icons.filled.Bolt +import androidx.compose.material.icons.filled.Code +import androidx.compose.material.icons.filled.Dns +import androidx.compose.material.icons.filled.EditNote +import androidx.compose.material.icons.filled.EditOff +import androidx.compose.material.icons.filled.FilterAlt +import androidx.compose.material.icons.filled.Gavel +import androidx.compose.material.icons.filled.History +import androidx.compose.material.icons.filled.Key +import androidx.compose.material.icons.filled.Language +import androidx.compose.material.icons.filled.Lock +import androidx.compose.material.icons.filled.Payment +import androidx.compose.material.icons.filled.PrivacyTip +import androidx.compose.material.icons.filled.Storage +import androidx.compose.material.icons.filled.Tag +import androidx.compose.material.icons.filled.Topic +import androidx.compose.material.icons.filled.Translate +import androidx.compose.material3.Card +import androidx.compose.material3.CardDefaults import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.HorizontalDivider +import androidx.compose.material3.Icon +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.OutlinedCard import androidx.compose.material3.Scaffold +import androidx.compose.material3.SuggestionChip import androidx.compose.material3.Text import androidx.compose.material3.TopAppBar import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.platform.LocalUriHandler +import androidx.compose.ui.text.buildAnnotatedString +import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp import com.vitorpamplona.amethyst.Amethyst import com.vitorpamplona.amethyst.R +import com.vitorpamplona.amethyst.commons.util.timeDiffAgoShortish import com.vitorpamplona.amethyst.model.nip11RelayInfo.loadRelayInfo import com.vitorpamplona.amethyst.ui.actions.CrossfadeIfEnabled -import com.vitorpamplona.amethyst.ui.components.ClickableEmail -import com.vitorpamplona.amethyst.ui.components.ClickableUrl -import com.vitorpamplona.amethyst.ui.components.TranslatableRichTextViewer +import com.vitorpamplona.amethyst.ui.components.appendLink +import com.vitorpamplona.amethyst.ui.navigation.navs.EmptyNav import com.vitorpamplona.amethyst.ui.navigation.navs.INav +import com.vitorpamplona.amethyst.ui.navigation.routes.Route import com.vitorpamplona.amethyst.ui.note.RenderRelayIcon import com.vitorpamplona.amethyst.ui.note.UserCompose -import com.vitorpamplona.amethyst.ui.note.timeAgo +import com.vitorpamplona.amethyst.ui.note.graspLink +import com.vitorpamplona.amethyst.ui.note.nipLink +import com.vitorpamplona.amethyst.ui.note.timeAgoNoDot import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.rooms.LoadUser +import com.vitorpamplona.amethyst.ui.screen.loggedIn.mockAccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.qrcode.BackButton import com.vitorpamplona.amethyst.ui.stringRes -import com.vitorpamplona.amethyst.ui.theme.DoubleHorzSpacer -import com.vitorpamplona.amethyst.ui.theme.DoubleVertSpacer -import com.vitorpamplona.amethyst.ui.theme.HalfVertSpacer -import com.vitorpamplona.amethyst.ui.theme.LargeRelayIconModifier -import com.vitorpamplona.amethyst.ui.theme.Size10dp +import com.vitorpamplona.amethyst.ui.theme.Size100dp import com.vitorpamplona.amethyst.ui.theme.StdHorzSpacer -import com.vitorpamplona.amethyst.ui.theme.StdPadding import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer -import com.vitorpamplona.quartz.nip01Core.core.EmptyTagList -import com.vitorpamplona.quartz.nip01Core.relay.client.stats.RelayDebugMessage +import com.vitorpamplona.amethyst.ui.theme.ThemeComparisonRow +import com.vitorpamplona.quartz.nip01Core.relay.client.stats.ErrorDebugMessage +import com.vitorpamplona.quartz.nip01Core.relay.client.stats.IRelayDebugMessage +import com.vitorpamplona.quartz.nip01Core.relay.client.stats.NoticeDebugMessage +import com.vitorpamplona.quartz.nip01Core.relay.client.stats.RelayStat +import com.vitorpamplona.quartz.nip01Core.relay.client.stats.SpamDebugMessage import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl import com.vitorpamplona.quartz.nip01Core.relay.normalizer.RelayUrlNormalizer import com.vitorpamplona.quartz.nip01Core.relay.normalizer.displayUrl +import com.vitorpamplona.quartz.nip11RelayInfo.Nip11RelayInformation +import com.vitorpamplona.quartz.utils.TimeUtils +import kotlinx.collections.immutable.ImmutableList +import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.toImmutableList +import kotlin.contracts.ExperimentalContracts +import kotlin.contracts.contract @Composable fun RelayInformationScreen( @@ -138,267 +186,177 @@ fun RelayInformationScreen( .toImmutableList() } - LazyColumn( - modifier = - Modifier - .padding(pad) - .consumeWindowInsets(pad) - .padding(bottom = Size10dp, start = Size10dp, end = Size10dp) - .fillMaxSize(), - ) { - item { - Row( - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.Center, - modifier = StdPadding.fillMaxWidth(), - ) { - Column { - RenderRelayIcon( - displayUrl = relay.displayUrl(), - iconUrl = relayInfo.icon, - loadProfilePicture = accountViewModel.settings.showProfilePictures(), - loadRobohash = accountViewModel.settings.isNotPerformanceMode(), - pingInMs = - Amethyst.instance.relayStats - .get(relay) - .pingInMs, - iconModifier = LargeRelayIconModifier, - ) - } - - Spacer(modifier = DoubleHorzSpacer) - - Column(horizontalAlignment = Alignment.CenterHorizontally) { - Title(relayInfo.name?.trim() ?: "") - Spacer(modifier = HalfVertSpacer) - SubtitleContent(relay.url) - } - } - } - item { - Section(stringRes(R.string.description)) - - SectionContent(relayInfo.description?.trim() ?: stringRes(R.string.no_description)) - } - relayInfo.pubkey?.let { - item { - Section(stringRes(R.string.owner)) - DisplayOwnerInformation(it, accountViewModel, nav) - } - } - relayInfo.contact?.let { - item { - Section(stringRes(R.string.contact)) - - Box(modifier = Modifier.padding(start = 10.dp)) { - if (it.startsWith("https:")) { - ClickableUrl(urlText = it, url = it) - } else if (it.startsWith("mailto:") || it.contains('@')) { - ClickableEmail(it) - } else { - SectionContent(it) - } - } - } - } - relayInfo.software?.let { - item { - Section(stringRes(R.string.software)) - - DisplaySoftwareInformation(it) - - Section(stringRes(R.string.version)) - - SectionContent(relayInfo.version ?: "") - } - } - relayInfo.supported_nips?.let { - if (it.isNotEmpty()) { - item { - Section(stringRes(R.string.supports)) - - DisplaySupportedNips(it, relayInfo.supported_nip_extensions) - } - } - } - relayInfo.fees?.admission?.let { - item { - if (it.isNotEmpty()) { - Section(stringRes(R.string.admission_fees)) - - it.forEach { item -> SectionContent("${item.amount?.div(1000) ?: 0} sats") } - } - } - } - - relayInfo.payments_url?.let { - item { - Section(stringRes(R.string.payments_url)) - - Box(modifier = Modifier.padding(start = 10.dp)) { - ClickableUrl( - urlText = it, - url = it, - ) - } - } - } - - relayInfo.limitation?.let { - item { - Section(stringRes(R.string.limitations)) - val authRequiredText = - if (it.auth_required ?: false) stringRes(R.string.yes) else stringRes(R.string.no) - - val paymentRequiredText = - if (it.payment_required ?: false) stringRes(R.string.yes) else stringRes(R.string.no) - - val restrictedWritesText = - if (it.restricted_writes ?: false) stringRes(R.string.yes) else stringRes(R.string.no) - - Column { - SectionContent( - "${stringRes(R.string.message_length)}: ${it.max_message_length ?: 0}", - ) - SectionContent( - "${stringRes(R.string.subscriptions)}: ${it.max_subscriptions ?: 0}", - ) - SectionContent("${stringRes(R.string.filters)}: ${it.max_filters ?: 0}") - SectionContent( - "${stringRes(R.string.subscription_id_length)}: ${it.max_subid_length ?: 0}", - ) - SectionContent("${stringRes(R.string.minimum_prefix)}: ${it.min_prefix ?: 0}") - SectionContent( - "${stringRes(R.string.maximum_event_tags)}: ${it.max_event_tags ?: 0}", - ) - SectionContent( - "${stringRes(R.string.content_length)}: ${it.max_content_length ?: 0}", - ) - SectionContent( - "${stringRes(R.string.max_limit)}: ${it.max_limit ?: 0}", - ) - SectionContent("${stringRes(R.string.minimum_pow)}: ${it.min_pow_difficulty ?: 0}") - SectionContent("${stringRes(R.string.auth)}: $authRequiredText") - SectionContent("${stringRes(R.string.payment)}: $paymentRequiredText") - SectionContent("${stringRes(R.string.restricted_writes)}: $restrictedWritesText") - } - } - } - relayInfo.relay_countries?.let { - item { - Section(stringRes(R.string.countries)) - - FlowRow { it.forEach { item -> SectionContent(item) } } - } - } - relayInfo.language_tags?.let { - item { - Section(stringRes(R.string.languages)) - - FlowRow { it.forEach { item -> SectionContent(item) } } - } - } - relayInfo.tags?.let { - item { - Section(stringRes(R.string.tags)) - - FlowRow { it.forEach { item -> SectionContent(item) } } - } - } - relayInfo.posting_policy?.let { - item { - Section(stringRes(R.string.posting_policy)) - - Box(Modifier.padding(10.dp)) { - ClickableUrl( - it, - it, - ) - } - } - } - - item { - Section(stringRes(R.string.relay_error_messages)) - } - - items(messages) { msg -> - Row { - RenderDebugMessage(msg, accountViewModel, nav) - } - - Spacer(modifier = StdVertSpacer) - } - } + RelayInformationBody(relay, relayInfo, Amethyst.instance.relayStats.get(relay), messages, pad, accountViewModel, nav) } } @Composable -private fun RenderDebugMessage( - msg: RelayDebugMessage, +fun RelayInformationBody( + relay: NormalizedRelayUrl, + relayInfo: Nip11RelayInformation, + relayStats: RelayStat, + messages: ImmutableList, + pad: PaddingValues, accountViewModel: AccountViewModel, - newNav: INav, + nav: INav, ) { - SelectionContainer { - val context = LocalContext.current - val color = - remember { - mutableStateOf(Color.Transparent) - } - TranslatableRichTextViewer( - content = - remember { - "${timeAgo(msg.time, context)}, ${msg.type.name}: ${msg.message}" - }, - canPreview = false, - quotesLeft = 0, - modifier = Modifier.fillMaxWidth(), - tags = EmptyTagList, - backgroundColor = color, - id = msg.hashCode().toString(), - accountViewModel = accountViewModel, - nav = newNav, - ) - } -} + LazyColumn( + modifier = + Modifier + .padding(pad) + .consumeWindowInsets(pad) + .fillMaxSize(), + contentPadding = PaddingValues(10.dp), + verticalArrangement = Arrangement.spacedBy(10.dp), + ) { + // 1. Header Section + item { + RelayHeader(relay, relayStats, relayInfo, accountViewModel) + } -@Composable -@OptIn(ExperimentalLayoutApi::class) -private fun DisplaySupportedNips( - supportedNips: List, - supportedNipExtensions: List?, -) { - FlowRow { - supportedNips.forEach { item -> - val text = item.toString().padStart(2, '0') - Box(Modifier.padding(10.dp)) { - ClickableUrl( - urlText = text, - url = "https://github.com/nostr-protocol/nips/blob/master/$text.md", - ) + val targetAudience = + relayInfo.tags != null || + relayInfo.language_tags != null || + relayInfo.relay_countries != null + + if (targetAudience) { + item { SectionHeader(stringRes(R.string.target_audience)) } + item { TargetAudienceCard(relayInfo, nav) } + } + + relayInfo.pubkey?.let { + item { + SectionHeader(stringRes(R.string.owner)) + DisplayOwnerInformation(it, accountViewModel, nav) } } - supportedNipExtensions?.forEach { item -> - val text = item.padStart(2, '0') - Box(Modifier.padding(10.dp)) { - ClickableUrl( - urlText = text, - url = "https://github.com/nostr-protocol/nips/blob/master/$text.md", - ) + relayInfo.self?.let { + item { + SectionHeader(stringRes(R.string.self)) + DisplayOwnerInformation(it, accountViewModel, nav) } } + + item { SectionHeader(stringRes(R.string.policies_and_links)) } + item { PoliciesCard(relayInfo) } + + relayInfo.fees?.let { fees -> + item { SectionHeader(stringRes(R.string.fees_and_payments)) } + item { FeesCard(fees, relayInfo.payments_url) } + } + + relayInfo.limitation?.let { + item { SectionHeader(stringRes(R.string.limitations)) } + item { LimitationsCard(it) } + } + + val atLeastOneSoftware = + relayInfo.software != null || + relayInfo.version != null || + relayInfo.supported_grasps != null || + relayInfo.supported_nips != null + + if (atLeastOneSoftware) { + item { SectionHeader(stringRes(R.string.software)) } + item { SoftwareCard(relayInfo) } + } + + item { + SectionHeader(stringRes(R.string.relay_error_messages)) + } + + items(messages) { msg -> + RenderDebugMessage(msg) + + Spacer(modifier = StdVertSpacer) + } } } @Composable -private fun DisplaySoftwareInformation(software: String) { - val url = software.replace("git+", "") - Box(modifier = Modifier.padding(start = 10.dp)) { - ClickableUrl( - urlText = url, - url = url, - ) +private fun RenderDebugMessage(msg: IRelayDebugMessage) { + val context = LocalContext.current + + Column(Modifier.padding(horizontal = 12.dp)) { + Row( + modifier = Modifier.padding(vertical = 6.dp), + verticalAlignment = Alignment.Top, + horizontalArrangement = Arrangement.spacedBy(12.dp), + ) { + // Timestamp with Monospace font for alignment + Text( + text = timeAgoNoDot(msg.time, context), + style = MaterialTheme.typography.labelSmall.copy(fontFamily = FontFamily.Monospace), + color = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.6f), + ) + + // Type Tag + Text( + text = + when (msg) { + is ErrorDebugMessage -> stringRes(R.string.errors) + is NoticeDebugMessage -> stringRes(R.string.relay_notice) + is SpamDebugMessage -> stringRes(R.string.spam) + }, + style = + MaterialTheme.typography.labelSmall.copy( + fontWeight = FontWeight.Bold, + fontFamily = FontFamily.Monospace, + ), + color = + when (msg) { + is ErrorDebugMessage -> MaterialTheme.colorScheme.error + is NoticeDebugMessage -> MaterialTheme.colorScheme.primary + is SpamDebugMessage -> MaterialTheme.colorScheme.outline + }, + ) + } + + when (msg) { + is ErrorDebugMessage -> + SelectionContainer { + Text( + text = msg.message, + style = MaterialTheme.typography.bodySmall.copy(fontFamily = FontFamily.Monospace), + color = MaterialTheme.colorScheme.onSurface, + ) + } + is NoticeDebugMessage -> + SelectionContainer { + Text( + text = msg.message, + style = MaterialTheme.typography.bodySmall.copy(fontFamily = FontFamily.Monospace), + color = MaterialTheme.colorScheme.onSurface, + ) + } + is SpamDebugMessage -> + SelectionContainer { + val uri = LocalUriHandler.current + val start = stringRes(R.string.duplicated_post) + Text( + text = + remember { + buildAnnotatedString { + append(start) + append(" ") + appendLink(msg.link1) { + runCatching { + uri.openUri(msg.link1) + } + } + appendLink(msg.link2) { + runCatching { + uri.openUri(msg.link2) + } + } + } + }, + style = MaterialTheme.typography.bodySmall.copy(fontFamily = FontFamily.Monospace), + color = MaterialTheme.colorScheme.onSurface, + ) + } + } } } @@ -408,50 +366,616 @@ private fun DisplayOwnerInformation( accountViewModel: AccountViewModel, nav: INav, ) { - LoadUser(baseUserHex = userHex, accountViewModel) { - CrossfadeIfEnabled(it, accountViewModel = accountViewModel) { + LoadUser(baseUserHex = userHex, accountViewModel) { loadedUser -> + CrossfadeIfEnabled(loadedUser, accountViewModel = accountViewModel) { if (it != null) { - UserCompose( - baseUser = it, - accountViewModel = accountViewModel, - nav = nav, - ) + Card(colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surfaceVariant)) { + UserCompose( + baseUser = it, + accountViewModel = accountViewModel, + nav = nav, + ) + } } } } } @Composable -fun Title(text: String) { +private fun RelayHeader( + relay: NormalizedRelayUrl, + relayStats: RelayStat, + relayInfo: Nip11RelayInformation, + accountViewModel: AccountViewModel, +) { + Column( + horizontalAlignment = Alignment.CenterHorizontally, + modifier = + Modifier + .fillMaxWidth() + .padding(horizontal = 16.dp), + ) { + RenderRelayIcon( + displayUrl = relay.displayUrl(), + iconUrl = relayInfo.icon, + loadProfilePicture = accountViewModel.settings.showProfilePictures(), + loadRobohash = accountViewModel.settings.isNotPerformanceMode(), + pingInMs = relayStats.pingInMs, + iconModifier = + Modifier + .size(Size100dp) + .clip(shape = CircleShape), + ) + Spacer(modifier = Modifier.height(12.dp)) + Text( + text = relayInfo.description ?: relay.displayUrl(), + style = MaterialTheme.typography.bodyLarge, + color = MaterialTheme.colorScheme.onSurfaceVariant, + textAlign = TextAlign.Center, + ) + } +} + +@Composable +fun FeesCard( + fees: Nip11RelayInformation.RelayInformationFees, + payUrl: String?, +) { + OutlinedCard(colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surfaceVariant)) { + Column(modifier = Modifier.padding(16.dp)) { + fees.admission?.forEach { + FeeRow(stringRes(R.string.admission), it) + } + fees.subscription?.forEach { + FeeRow(stringRes(R.string.subscription), it) + } + fees.publication?.forEach { + FeeRow(stringRes(R.string.publication), it) + } + payUrl?.let { + val uri = LocalUriHandler.current + ClickableInfoRow(Icons.Default.Payment, stringRes(R.string.payments_url), it.removePrefix("https://")) { + runCatching { + uri.openUri(it) + } + } + } + } + } +} + +@Composable +fun LimitationsCard(lim: Nip11RelayInformation.RelayInformationLimitation) { + OutlinedCard(colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surfaceVariant)) { + Column(modifier = Modifier.padding(16.dp), verticalArrangement = Arrangement.spacedBy(8.dp)) { + val atLeastOneAccessControl = + lim.auth_required != null || + lim.payment_required != null || + lim.restricted_writes != null || + lim.min_pow_difficulty != null || + lim.min_prefix != null + + if (atLeastOneAccessControl) { + Column { + Text(stringRes(R.string.access_control), style = MaterialTheme.typography.labelMedium, color = MaterialTheme.colorScheme.primary) + HorizontalDivider(modifier = Modifier.padding(vertical = 8.dp)) + + val yes = stringRes(R.string.yes) + val no = stringRes(R.string.no) + + lim.auth_required?.let { + InfoRow(Icons.Default.History, stringRes(R.string.auth_required), if (it) yes else no) + } + lim.payment_required?.let { + InfoRow(Icons.Default.Lock, stringRes(R.string.payment_required), if (it) yes else no) + } + lim.restricted_writes?.let { + InfoRow(Icons.Default.EditOff, stringRes(R.string.restricted_writes), if (it) yes else no) + } + + val minPoW = lim.min_pow_difficulty + + if (minPoW != null && minPoW > 0) { + InfoRow(Icons.Default.Bolt, stringRes(R.string.minimum_pow), stringRes(R.string.amount_in_bits, minPoW)) + } else { + lim.min_prefix?.let { + if (it > 0) { + InfoRow(Icons.Default.Key, stringRes(R.string.minimum_prefix), stringRes(R.string.amount_in_bits, it * 8)) + } + } + } + } + } + + val atLeastOneConnectivity = + lim.max_message_length.isNotNullAndNotZero() || + lim.max_subscriptions.isNotNullAndNotZero() || + lim.max_filters.isNotNullAndNotZero() || + lim.max_limit.isNotNullAndNotZero() || + lim.default_limit.isNotNullAndNotZero() || + lim.max_subid_length.isNotNullAndNotZero() + + if (atLeastOneConnectivity) { + Column { + Text(stringRes(R.string.connectivity), style = MaterialTheme.typography.labelMedium, color = MaterialTheme.colorScheme.primary) + + HorizontalDivider(modifier = Modifier.padding(vertical = 8.dp)) + + lim.max_message_length?.let { + InfoRow(Icons.AutoMirrored.Default.Message, stringRes(R.string.max_message_length), "${it / 1024} kb") + } + lim.max_subscriptions?.let { + InfoRow(Icons.Default.Dns, stringRes(R.string.max_subs), it.toString()) + } + lim.max_filters?.let { + InfoRow(Icons.Default.FilterAlt, stringRes(R.string.max_filters_per_sub), it.toString()) + } + lim.max_limit?.let { + InfoRow(Icons.AutoMirrored.Default.List, stringRes(R.string.max_limit_events_returning), it.toString()) + } + lim.default_limit?.let { + InfoRow(Icons.AutoMirrored.Default.List, stringRes(R.string.max_limit_events_returning), it.toString()) + } + lim.max_subid_length?.let { + InfoRow(Icons.AutoMirrored.Default.Label, stringRes(R.string.max_subid_length), it.toString()) + } + } + } + + val atLeastOneContentSize = + lim.max_event_tags != null || + lim.max_content_length != null + + if (atLeastOneContentSize) { + Column { + Text(stringRes(R.string.content_size), style = MaterialTheme.typography.labelMedium, color = MaterialTheme.colorScheme.primary) + + HorizontalDivider(modifier = Modifier.padding(vertical = 8.dp)) + + lim.max_event_tags?.let { + InfoRow(Icons.Default.Tag, stringRes(R.string.maximum_event_tags), it.toString()) + } + + lim.max_content_length?.let { + InfoRow(Icons.AutoMirrored.Default.Article, stringRes(R.string.max_content_length), "${it / 1024} kb") + } + } + } + + val atLeastOneRestriction = + lim.created_at_lower_limit.isNotNullAndNotZero() || + lim.created_at_upper_limit.isNotNullAndNotZero() + + if (atLeastOneRestriction) { + Column { + Text(stringRes(R.string.event_retention), style = MaterialTheme.typography.labelMedium, color = MaterialTheme.colorScheme.primary) + + HorizontalDivider(modifier = Modifier.padding(vertical = 8.dp)) + + lim.created_at_lower_limit?.let { + if (it > 0) { + InfoRow(Icons.Default.History, stringRes(R.string.discards_older_than), stringRes(R.string.time_in_the_past, timeDiffAgoShortish(it))) + } + } + lim.created_at_upper_limit?.let { + if (it > 0) { + InfoRow(Icons.Default.History, stringRes(R.string.accepts_up_to), stringRes(R.string.time_in_the_future, timeDiffAgoShortish(it))) + } + } + } + } + } + } +} + +@OptIn(ExperimentalContracts::class) +fun Int?.isNotNullAndNotZero(): Boolean { + contract { + returns(true) implies (this@isNotNullAndNotZero != null) + } + + return this != null && this != 0 +} + +@Composable +fun SoftwareCard(relayInfo: Nip11RelayInformation) { + OutlinedCard(colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surfaceVariant)) { + Column(modifier = Modifier.padding(16.dp)) { + val uri = LocalUriHandler.current + relayInfo.software?.let { + if (it.contains("https://")) { + ClickableInfoRow(Icons.Default.Code, stringRes(R.string.software), it.removePrefix("git+https://").removePrefix("https://")) { + runCatching { + uri.openUri(it.removePrefix("git+")) + } + } + } else { + InfoRow(Icons.Default.Code, stringRes(R.string.software), it) + } + } + + relayInfo.version?.let { + InfoRow(Icons.Default.Storage, stringRes(R.string.version), it) + } + + relayInfo.supported_nips?.let { nips -> + Text( + stringRes(R.string.supports), + modifier = Modifier.padding(top = 8.dp), + style = MaterialTheme.typography.labelMedium, + color = MaterialTheme.colorScheme.primary, + ) + HorizontalDivider(modifier = Modifier.padding(vertical = 8.dp)) + + val uri = LocalUriHandler.current + FlowRow( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.spacedBy(8.dp), + ) { + nips.forEach { nip -> + val nipStr = nip.padStart(2, '0') + SuggestionChip( + onClick = { + runCatching { + uri.openUri(nipLink(nipStr)) + } + }, + label = { + Text(nipStr) + }, + ) + } + } + } + + relayInfo.supported_grasps?.let { grasps -> + Text( + stringRes(R.string.supported_grasps), + modifier = Modifier.padding(top = 8.dp), + style = MaterialTheme.typography.labelMedium, + color = MaterialTheme.colorScheme.primary, + ) + HorizontalDivider(modifier = Modifier.padding(vertical = 8.dp)) + + val uri = LocalUriHandler.current + FlowRow( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.spacedBy(8.dp), + ) { + grasps.forEach { grasp -> + val graspStr = grasp.padStart(2, '0') + SuggestionChip( + onClick = { + runCatching { + uri.openUri(graspLink(graspStr)) + } + }, + label = { + Text(graspStr) + }, + ) + } + } + } + } + } +} + +@Composable +fun TargetAudienceCard( + relay: Nip11RelayInformation, + nav: INav, +) { + OutlinedCard(colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surfaceVariant)) { + Column(modifier = Modifier.padding(16.dp)) { + relay.tags?.let { tags -> + if (tags.size > 2) { + Column { + Text(stringRes(R.string.topics), style = MaterialTheme.typography.labelMedium, color = MaterialTheme.colorScheme.primary) + + HorizontalDivider(modifier = Modifier.padding(vertical = 8.dp)) + + FlowRow( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.spacedBy(8.dp), + ) { + tags.forEach { tag -> + SuggestionChip( + onClick = { nav.nav(Route.Hashtag(tag)) }, + label = { + Text(tag) + }, + ) + } + } + } + } else if (tags.isNotEmpty()) { + InfoRow(Icons.Default.Topic, stringRes(R.string.topics), tags.joinToString()) + } + } + relay.relay_countries?.let { countries -> + val allCountries = stringRes(R.string.all_countries) + if (countries.size > 2) { + Column { + Text(stringRes(R.string.countries), style = MaterialTheme.typography.labelMedium, color = MaterialTheme.colorScheme.primary) + + HorizontalDivider(modifier = Modifier.padding(vertical = 8.dp)) + + FlowRow( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.spacedBy(8.dp), + ) { + countries.forEach { country -> + if (country == "*") { + SuggestionChip( + onClick = { }, + label = { + Text(allCountries) + }, + ) + } else { + SuggestionChip( + onClick = { }, + label = { + Text(country) + }, + ) + } + } + } + + Spacer(modifier = Modifier.height(16.dp)) + } + } else if (countries.isNotEmpty()) { + InfoRow( + Icons.Default.Language, + stringRes(R.string.countries), + countries.joinToString { + if (it == "*") allCountries else it + }, + ) + } + } + relay.language_tags?.let { languages -> + val allLang = stringRes(R.string.all_languages) + if (languages.size > 2) { + Column { + Text(stringRes(R.string.languages), style = MaterialTheme.typography.labelMedium, color = MaterialTheme.colorScheme.primary) + + HorizontalDivider(modifier = Modifier.padding(vertical = 8.dp)) + + FlowRow( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.spacedBy(8.dp), + ) { + languages.forEach { lang -> + if (lang == "*") { + SuggestionChip( + onClick = { }, + label = { + Text(allLang) + }, + ) + } else { + SuggestionChip( + onClick = { }, + label = { + Text(lang) + }, + ) + } + } + } + } + } else if (languages.isNotEmpty()) { + InfoRow( + Icons.Default.Translate, + stringRes(R.string.languages), + languages.joinToString { + if (it == "*") allLang else it + }, + ) + } + } + } + } +} + +@Composable +fun PoliciesCard(relay: Nip11RelayInformation) { + OutlinedCard(colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surfaceVariant)) { + Column(modifier = Modifier.padding(16.dp)) { + val uri = LocalUriHandler.current + relay.contact?.let { + if (it.contains("@")) { + ClickableInfoRow(Icons.AutoMirrored.Default.ContactSupport, stringRes(R.string.contact), it) { + runCatching { + uri.openUri("mailto:$it") + } + } + } else { + InfoRow(Icons.AutoMirrored.Default.ContactSupport, stringRes(R.string.contact), it) + } + } + + relay.posting_policy?.let { + ClickableInfoRow(Icons.Default.EditNote, stringRes(R.string.posting_policy), it) { + runCatching { + uri.openUri(it) + } + } + } + + val pp = relay.privacy_policy + + if (pp != null) { + ClickableInfoRow(Icons.Default.PrivacyTip, stringRes(R.string.privacy_policy), pp.removePrefix("https://")) { + runCatching { + uri.openUri(pp) + } + } + } else { + InfoRow(Icons.Default.PrivacyTip, stringRes(R.string.privacy_policy), stringRes(R.string.not_available_acronym)) + } + + val ts = relay.terms_of_service + if (ts != null) { + ClickableInfoRow(Icons.Default.Gavel, stringRes(R.string.terms_and_conditions), ts.removePrefix("https://")) { + runCatching { + uri.openUri(ts) + } + } + } else { + InfoRow(Icons.Default.Gavel, stringRes(R.string.terms_and_conditions), stringRes(R.string.not_available_acronym)) + } + } + } +} + +@Composable +fun SectionHeader(title: String) { Text( - text = text, + text = title, + style = MaterialTheme.typography.titleMedium, fontWeight = FontWeight.Bold, - fontSize = 24.sp, + modifier = Modifier.padding(top = 5.dp), + color = MaterialTheme.colorScheme.primary, ) } @Composable -fun SubtitleContent(text: String) { - Text( - text = text, - ) +private fun InfoRow( + icon: ImageVector, + label: String, + value: String, +) { + Row( + modifier = Modifier.padding(vertical = 4.dp), + verticalAlignment = Alignment.CenterVertically, + ) { + Icon(icon, contentDescription = null, modifier = Modifier.size(18.dp), tint = MaterialTheme.colorScheme.secondary) + Spacer(Modifier.width(12.dp)) + Text(text = label, style = MaterialTheme.typography.labelLarge, maxLines = 1) + Text(text = value, textAlign = TextAlign.End, style = MaterialTheme.typography.bodyMedium, fontWeight = FontWeight.SemiBold, modifier = Modifier.weight(1f), overflow = TextOverflow.Ellipsis, maxLines = 1) + } } @Composable -fun Section(text: String) { - Spacer(modifier = DoubleVertSpacer) - Text( - text = text, - fontWeight = FontWeight.Bold, - fontSize = 20.sp, - ) - Spacer(modifier = DoubleVertSpacer) +private fun ClickableInfoRow( + icon: ImageVector, + label: String, + value: String, + onClickValue: () -> Unit, +) { + Row( + modifier = Modifier.padding(vertical = 4.dp), + verticalAlignment = Alignment.CenterVertically, + ) { + Icon(icon, contentDescription = null, modifier = Modifier.size(18.dp), tint = MaterialTheme.colorScheme.secondary) + Spacer(Modifier.width(12.dp)) + Text(text = label, style = MaterialTheme.typography.labelLarge, maxLines = 1) + Text(text = value, textAlign = TextAlign.End, style = MaterialTheme.typography.bodyMedium, fontWeight = FontWeight.SemiBold, modifier = Modifier.clickable(onClick = onClickValue).weight(1f), overflow = TextOverflow.Ellipsis, maxLines = 1) + } } @Composable -fun SectionContent(text: String) { - Text( - modifier = Modifier.padding(start = 10.dp), - text = text, - ) +fun FeeRow( + label: String, + fee: Nip11RelayInformation.RelayInformationFee, +) { + fee.amount?.let { + val period = fee.period + val combinedLabel = + if (period != null) { + label + " (${timeDiffAgoShortish(period)})" + } else { + label + } + + if (fee.unit == "msats") { + InfoRow(Icons.Default.AttachMoney, combinedLabel, "${it / 1000} sats") + } else { + InfoRow(Icons.Default.AttachMoney, combinedLabel, "$it ${fee.unit}") + } + } +} + +@Composable +@Preview(showBackground = true, name = "Nost.wine Relay Info", device = "spec:width=2160px,height=5640px,dpi=440") +fun RelayHeaderPreview() { + ThemeComparisonRow { + RelayInformationBody( + relay = NormalizedRelayUrl("wss://nostr.wine/"), + relayInfo = + Nip11RelayInformation( + name = "Nostr.wine", + icon = "https://image.nostr.build/30acdce4a81926f386622a07343228ae99fa68d012d54c538c0b2129dffe400c.png", + description = "A paid nostr relay for wine enthusiasts and everyone else", + software = "https://nostr.wine", + contact = "wino@nostr.wine", + version = "0.3.3", + self = "4918eb332a41b71ba9a74b1dc64276cfff592e55107b93baae38af3520e55975", + pubkey = "4918eb332a41b71ba9a74b1dc64276cfff592e55107b93baae38af3520e55975", + payments_url = "https://nostr.wine/invoices", + privacy_policy = "https://nostr.wine/terms", + terms_of_service = "https://nostr.wine/terms", + tags = listOf("Bitcoin", "Amethyst"), + supported_nips = listOf("1", "2", "4", "9", "11", "40", "42", "50", "70", "77"), + relay_countries = listOf("*"), + language_tags = listOf("*"), + limitation = + Nip11RelayInformation.RelayInformationLimitation( + auth_required = false, + created_at_lower_limit = 94608000, + created_at_upper_limit = 300, + max_event_tags = 4000, + max_limit = 1000, + default_limit = 20, + max_message_length = 524288, + max_subid_length = 71, + max_subscriptions = 50, + min_pow_difficulty = 0, + payment_required = true, + restricted_writes = true, + ), + fees = + Nip11RelayInformation.RelayInformationFees( + admission = + listOf( + Nip11RelayInformation.RelayInformationFee( + amount = 3000, + unit = "msats", + period = 2628003, + ), + Nip11RelayInformation.RelayInformationFee( + amount = 8000, + unit = "sats", + period = 7884009, + ), + ), + ), + supported_grasps = listOf("GRASP-01"), + ), + pad = PaddingValues(0.dp), + relayStats = RelayStat(), + messages = + persistentListOf( + NoticeDebugMessage( + time = TimeUtils.now(), + message = "Subscription closed: AccountNotificationsEoseFromRandomRelaysManagerugZU9o auth-required: At least one matching event requires AUTH", + ), + ErrorDebugMessage( + time = TimeUtils.now() - 24000, + message = "No such subscription", + ), + SpamDebugMessage( + time = TimeUtils.now() - 24000, + link1 = "http://test1.com", + link2 = "http://test2.com", + ), + ), + accountViewModel = mockAccountViewModel(), + nav = EmptyNav(), + ) + } } diff --git a/amethyst/src/main/res/values/strings.xml b/amethyst/src/main/res/values/strings.xml index 9542f59a9..212407e46 100644 --- a/amethyst/src/main/res/values/strings.xml +++ b/amethyst/src/main/res/values/strings.xml @@ -17,6 +17,8 @@ Could not decrypt the message Group Picture Explicit Content + Relay Notice + Duplicated Post Spam The number of spamming events coming from this relay Impersonation @@ -133,6 +135,7 @@ Relay Address Posts Bytes + Error Errors The number of connection errors in this session Home Feed @@ -747,28 +750,64 @@ The amount in bytes that was received from this relay, including filters and events An error occurred trying to get relay information from %1$s Owner + Service Key + Running %1$s + Running %1$s (%2$s) Version Software Contact Supported NIPs + Supported Grasps Admission Fees + Admission + Subscription + Publication + Payments %1$s Payments url + Target Audience + Policies & Links + Fees & Payments Limitations Countries Languages Tags + Topics + All Countries + All Languages Posting policy + Privacy Policy + Terms & Conditions + N/A Errors and Notices from this Relay Message length Subscriptions Filters Subscription id length - Minimum prefix - Maximum event tags + Min Prefix + Max Event Tags Content length - Minimum PoW + Max Content Length + Discards older than + Accepts up to + %1$s in the future + %1$s ago + %1$s zeros + %1$s bits + Event Retention + Content Size + Connectivity + Access Control + Min PoW Difficulty Auth + Auth Required Payment + Payment Required + Max Message Length + Max Subscriptions + Max Filters per Sub + Max Limit (Events Returning) + Default Limit (Events Returning) + Max SubID Length Cashu Token Redeem Send to Zap Wallet diff --git a/commons/src/jvmAndroid/kotlin/com/vitorpamplona/amethyst/commons/util/TimeAgoFormatter.kt b/commons/src/jvmAndroid/kotlin/com/vitorpamplona/amethyst/commons/util/TimeAgoFormatter.kt index 88ef514b9..12307ecd2 100644 --- a/commons/src/jvmAndroid/kotlin/com/vitorpamplona/amethyst/commons/util/TimeAgoFormatter.kt +++ b/commons/src/jvmAndroid/kotlin/com/vitorpamplona/amethyst/commons/util/TimeAgoFormatter.kt @@ -20,6 +20,7 @@ */ package com.vitorpamplona.amethyst.commons.util +import com.sun.org.apache.xalan.internal.lib.ExsltDatetime.time import com.vitorpamplona.quartz.utils.TimeUtils import java.text.SimpleDateFormat import java.util.Locale @@ -81,6 +82,50 @@ fun timeAgo( } } +fun timeDiffAgoLong(timeDifference: Int): String = + when { + timeDifference > TimeUtils.ONE_YEAR -> { + (timeDifference / TimeUtils.ONE_YEAR).toString() + " years" + } + timeDifference > TimeUtils.ONE_MONTH -> { + (timeDifference / TimeUtils.ONE_MONTH).toString() + " months" + } + timeDifference > TimeUtils.ONE_DAY -> { + (timeDifference / TimeUtils.ONE_DAY).toString() + " days" + } + timeDifference > TimeUtils.ONE_HOUR -> { + (timeDifference / TimeUtils.ONE_HOUR).toString() + " hours" + } + timeDifference > TimeUtils.ONE_MINUTE -> { + (timeDifference / TimeUtils.ONE_MINUTE).toString() + " minutes" + } + else -> { + "now" + } + } + +fun timeDiffAgoShortish(timeDifference: Int): String = + when { + timeDifference > TimeUtils.ONE_YEAR -> { + (timeDifference / TimeUtils.ONE_YEAR).toString() + " yrs" + } + timeDifference > TimeUtils.ONE_MONTH -> { + (timeDifference / TimeUtils.ONE_MONTH).toString() + " mos" + } + timeDifference > TimeUtils.ONE_DAY -> { + (timeDifference / TimeUtils.ONE_DAY).toString() + " days" + } + timeDifference > TimeUtils.ONE_HOUR -> { + (timeDifference / TimeUtils.ONE_HOUR).toString() + " hrs" + } + timeDifference > TimeUtils.ONE_MINUTE -> { + (timeDifference / TimeUtils.ONE_MINUTE).toString() + " mins" + } + else -> { + "now" + } + } + /** * Formats a Unix timestamp as a date string. * For recent dates (< 1 day), returns the provided today string. diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/stats/RelayStat.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/stats/RelayStat.kt index c7576094f..b51b8428c 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/stats/RelayStat.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/stats/RelayStat.kt @@ -21,8 +21,10 @@ package com.vitorpamplona.quartz.nip01Core.relay.client.stats import androidx.collection.LruCache +import androidx.compose.runtime.Stable import com.vitorpamplona.quartz.utils.TimeUtils +@Stable class RelayStat( var receivedBytes: Int = 0, var sentBytes: Int = 0, @@ -31,12 +33,11 @@ class RelayStat( var pingInMs: Int = 0, var compression: Boolean = false, ) { - val messages = LruCache(100) + val messages = LruCache(100) fun newNotice(notice: String?) { val debugMessage = - RelayDebugMessage( - type = RelayDebugMessageType.NOTICE, + NoticeDebugMessage( message = notice ?: "No error message provided", ) @@ -47,8 +48,7 @@ class RelayStat( errorCounter++ val debugMessage = - RelayDebugMessage( - type = RelayDebugMessageType.ERROR, + ErrorDebugMessage( message = error ?: "No error message provided", ) @@ -63,27 +63,35 @@ class RelayStat( sentBytes += bytesUsedInMemory } - fun newSpam(spamDescriptor: String) { + fun newSpam( + link1: String, + link2: String, + ) { spamCounter++ - val debugMessage = - RelayDebugMessage( - type = RelayDebugMessageType.SPAM, - message = spamDescriptor, - ) + val debugMessage = SpamDebugMessage(link1, link2) messages.put(debugMessage, debugMessage) } } -class RelayDebugMessage( - val type: RelayDebugMessageType, - val message: String, - val time: Long = TimeUtils.now(), -) - -enum class RelayDebugMessageType { - SPAM, - NOTICE, - ERROR, +@Stable +sealed interface IRelayDebugMessage { + val time: Long } + +class SpamDebugMessage( + val link1: String, + val link2: String, + override val time: Long = TimeUtils.now(), +) : IRelayDebugMessage + +class NoticeDebugMessage( + val message: String, + override val time: Long = TimeUtils.now(), +) : IRelayDebugMessage + +class ErrorDebugMessage( + val message: String, + override val time: Long = TimeUtils.now(), +) : IRelayDebugMessage diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/normalizer/NormalizedRelayUrl.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/normalizer/NormalizedRelayUrl.kt index dd9ec6f7c..1fb5ef244 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/normalizer/NormalizedRelayUrl.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/normalizer/NormalizedRelayUrl.kt @@ -20,6 +20,9 @@ */ package com.vitorpamplona.quartz.nip01Core.relay.normalizer +import androidx.compose.runtime.Stable + +@Stable data class NormalizedRelayUrl( val url: String, ) : Comparable { diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip11RelayInfo/FlexibleIntListSerializer.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip11RelayInfo/FlexibleIntListSerializer.kt index f29779ceb..eaf719fbc 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip11RelayInfo/FlexibleIntListSerializer.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip11RelayInfo/FlexibleIntListSerializer.kt @@ -21,6 +21,7 @@ package com.vitorpamplona.quartz.nip11RelayInfo import com.vitorpamplona.quartz.utils.Log +import com.vitorpamplona.quartz.utils.text import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.KSerializer import kotlinx.serialization.builtins.ListSerializer @@ -32,15 +33,14 @@ import kotlinx.serialization.json.JsonArray import kotlinx.serialization.json.JsonDecoder import kotlinx.serialization.json.JsonNull import kotlinx.serialization.json.JsonPrimitive -import kotlinx.serialization.json.int import kotlinx.serialization.json.jsonPrimitive -object FlexibleIntListSerializer : KSerializer?> { - private val listSerializer = ListSerializer(Int.serializer()) +object FlexibleIntListSerializer : KSerializer?> { + private val listSerializer = ListSerializer(String.serializer()) override val descriptor: SerialDescriptor = listSerializer.descriptor - override fun deserialize(decoder: Decoder): List? { + override fun deserialize(decoder: Decoder): List? { require(decoder is JsonDecoder) { "This serializer can only be used with Json format" } return when (val element = decoder.decodeJsonElement()) { @@ -51,7 +51,7 @@ object FlexibleIntListSerializer : KSerializer?> { is JsonArray -> { element.mapNotNull { arrayElement -> try { - arrayElement.jsonPrimitive.int + arrayElement.jsonPrimitive.text } catch (e: Exception) { // Skip elements that aren't valid integers (strings, booleans, floats, etc.) Log.w("FlexibleIntListSerializer", "Invalid element in array: $arrayElement", e) @@ -63,7 +63,7 @@ object FlexibleIntListSerializer : KSerializer?> { // Handle single integer format (malformed but found in the wild): 1 is JsonPrimitive if !element.isString -> { try { - listOf(element.int) + listOf(element.text) } catch (e: Exception) { // Can't parse as integer (e.g., float, boolean), treat as missing data Log.w("FlexibleIntListSerializer", "Invalid primitive: $element", e) @@ -79,7 +79,7 @@ object FlexibleIntListSerializer : KSerializer?> { @OptIn(ExperimentalSerializationApi::class) override fun serialize( encoder: Encoder, - value: List?, + value: List?, ) { if (value == null) { encoder.encodeNull() diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip11RelayInfo/Nip11RelayInformation.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip11RelayInfo/Nip11RelayInformation.kt index 593f20494..cdcaad58d 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip11RelayInfo/Nip11RelayInformation.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip11RelayInfo/Nip11RelayInformation.kt @@ -21,19 +21,22 @@ package com.vitorpamplona.quartz.nip11RelayInfo import androidx.compose.runtime.Stable +import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.JsonMapper import kotlinx.serialization.Serializable +@Stable @Serializable class Nip11RelayInformation( val id: String? = null, val name: String? = null, val description: String? = null, val icon: String? = null, - val pubkey: String? = null, + val pubkey: HexKey? = null, + val self: HexKey? = null, val contact: String? = null, @Serializable(with = FlexibleIntListSerializer::class) - val supported_nips: List? = null, + val supported_nips: List? = null, val supported_nip_extensions: List? = null, val software: String? = null, val version: String? = null, @@ -42,53 +45,60 @@ class Nip11RelayInformation( val language_tags: List? = null, val tags: List? = null, val posting_policy: String? = null, + val privacy_policy: String? = null, + val terms_of_service: String? = null, val payments_url: String? = null, val retention: List? = null, val fees: RelayInformationFees? = null, val nip50: List? = null, + val supported_grasps: List? = null, ) { companion object { fun fromJson(json: String): Nip11RelayInformation = JsonMapper.fromJson(json) } + + @Stable + @Serializable + class RelayInformationFee( + val amount: Int? = null, + val unit: String? = null, + val period: Int? = null, + val kinds: List? = null, + ) + + @Stable + @Serializable + class RelayInformationFees( + val admission: List? = null, + val subscription: List? = null, + val publication: List? = null, + ) + + @Stable + @Serializable + class RelayInformationLimitation( + val max_message_length: Int? = null, + val max_subscriptions: Int? = null, + val max_filters: Int? = null, + val max_limit: Int? = null, + val default_limit: Int? = null, + val max_subid_length: Int? = null, + val min_prefix: Int? = null, + val max_event_tags: Int? = null, + val max_content_length: Int? = null, + val min_pow_difficulty: Int? = null, + val auth_required: Boolean? = null, + val payment_required: Boolean? = null, + val restricted_writes: Boolean? = null, + val created_at_lower_limit: Int? = null, + val created_at_upper_limit: Int? = null, + ) + + @Stable + @Serializable + class RelayInformationRetentionData( + val kinds: ArrayList? = null, + val time: Int? = null, + val count: Int? = null, + ) } - -@Stable -@Serializable -class RelayInformationFee( - val amount: Int? = null, - val unit: String? = null, - val period: Int? = null, - val kinds: List? = null, -) - -@Serializable -class RelayInformationFees( - val admission: List? = null, - val subscription: List? = null, - val publication: List? = null, -) - -@Serializable -class RelayInformationLimitation( - val max_message_length: Int? = null, - val max_subscriptions: Int? = null, - val max_filters: Int? = null, - val max_limit: Int? = null, - val max_subid_length: Int? = null, - val min_prefix: Int? = null, - val max_event_tags: Int? = null, - val max_content_length: Int? = null, - val min_pow_difficulty: Int? = null, - val auth_required: Boolean? = null, - val payment_required: Boolean? = null, - val restricted_writes: Boolean? = null, - val created_at_lower_limit: Int? = null, - val created_at_upper_limit: Int? = null, -) - -@Serializable -class RelayInformationRetentionData( - val kinds: ArrayList? = null, - val time: Int? = null, - val count: Int? = null, -) From 3c85220c7c50e31adc397f2d5cb5ee2f323e3286 Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Tue, 6 Jan 2026 18:05:30 -0500 Subject: [PATCH 58/63] fixes package name --- .../com/vitorpamplona/amethyst/ui/layouts/DisappearingTopBar.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/layouts/DisappearingTopBar.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/layouts/DisappearingTopBar.kt index 26c9a82be..c701fb2a5 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/layouts/DisappearingTopBar.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/layouts/DisappearingTopBar.kt @@ -18,7 +18,7 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.myapplication +package com.vitorpamplona.amethyst.ui.layouts import androidx.compose.animation.core.AnimationSpec import androidx.compose.animation.core.AnimationState From f33e2fbcfb22717c0218566b3dd87a97d2c0c9ce Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Tue, 6 Jan 2026 18:06:24 -0500 Subject: [PATCH 59/63] Disables top bar reappearance to avoid the feed moving when coming back from page to page. --- .../vitorpamplona/amethyst/ui/layouts/DisappearingScaffold.kt | 2 -- .../com/vitorpamplona/amethyst/ui/layouts/DisappearingTopBar.kt | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/layouts/DisappearingScaffold.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/layouts/DisappearingScaffold.kt index 9cd3b289d..9525b7ef2 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/layouts/DisappearingScaffold.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/layouts/DisappearingScaffold.kt @@ -34,8 +34,6 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.theme.DividerThickness import com.vitorpamplona.myapplication.DisappearingBottomBar import com.vitorpamplona.myapplication.DisappearingFloatingButton -import com.vitorpamplona.myapplication.DisappearingTopBar -import com.vitorpamplona.myapplication.enterAlwaysScrollBehavior @OptIn(ExperimentalMaterial3Api::class) @Composable diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/layouts/DisappearingTopBar.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/layouts/DisappearingTopBar.kt index c701fb2a5..d03aca957 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/layouts/DisappearingTopBar.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/layouts/DisappearingTopBar.kt @@ -58,7 +58,7 @@ fun DisappearingTopBar( scrollBehavior: CustomEnterAlwaysScrollBehavior, content: @Composable (ColumnScope.() -> Unit), ) { - ResetDisappearingOnResume(scrollBehavior) + // ResetDisappearingOnResume(scrollBehavior) // Set up support for resizing the top app bar when vertically dragging the bar itself. val appBarDragModifier = From 93b139da622d24455e359f11fc4f448b49507b2c Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Tue, 6 Jan 2026 18:39:51 -0500 Subject: [PATCH 60/63] Fixes test case --- .../quartz/nip11RelayInfo/Nip11RelayInformationTest.kt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip11RelayInfo/Nip11RelayInformationTest.kt b/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip11RelayInfo/Nip11RelayInformationTest.kt index 3f8653f2d..75e267810 100644 --- a/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip11RelayInfo/Nip11RelayInformationTest.kt +++ b/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip11RelayInfo/Nip11RelayInformationTest.kt @@ -74,7 +74,7 @@ class Nip11RelayInformationTest { assertEquals("purplepag.es", info.name) assertEquals("Nostr's Purple Pages", info.description) assertEquals("fa984bd7dbb282f07e16e7ae87b26a2a7b9b90b7246a44771f0cf5ae58018f52", info.pubkey) - assertEquals(listOf(1, 2, 9, 11), info.supported_nips) + assertEquals(listOf("1", "2", "9", "11"), info.supported_nips) assertEquals("1.0.4", info.version) assertEquals("git+https://github.com/hoytech/strfry.git", info.software) } @@ -88,7 +88,7 @@ class Nip11RelayInformationTest { assertEquals("Nostr's Purple Pages", info.description) assertEquals("fa984bd7dbb282f07e16e7ae87b26a2a7b9b90b7246a44771f0cf5ae58018f52", info.pubkey) // Single integer should be converted to a list with one element - assertEquals(listOf(1), info.supported_nips) + assertEquals(listOf("1"), info.supported_nips) assertEquals("1.0.4", info.version) assertEquals("git+https://github.com/hoytech/strfry.git", info.software) } @@ -132,7 +132,7 @@ class Nip11RelayInformationTest { assertNotNull(info) assertEquals("test relay", info.name) // Should skip invalid elements and keep only valid integers - assertEquals(listOf(1, 3, 11), info.supported_nips) + assertEquals(listOf("1", "3", "11"), info.supported_nips) } @Test @@ -204,6 +204,6 @@ class Nip11RelayInformationTest { assertNotNull(info) assertEquals("test relay", info.name) - assertEquals((1..100).toList(), info.supported_nips) + assertEquals((1..100).map { it.toString() }, info.supported_nips) } } From 109150e693f4da23a66198d2251bb8ce50efe3fe Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Tue, 6 Jan 2026 18:53:18 -0500 Subject: [PATCH 61/63] These logs make everything go slow :( --- .../com/vitorpamplona/amethyst/service/logging/Logging.kt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/logging/Logging.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/logging/Logging.kt index 3175a2824..be4565568 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/logging/Logging.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/logging/Logging.kt @@ -21,7 +21,6 @@ package com.vitorpamplona.amethyst.service.logging import android.os.Build -import android.os.Looper import android.os.StrictMode import android.os.StrictMode.ThreadPolicy import android.os.StrictMode.VmPolicy @@ -59,8 +58,8 @@ class Logging { }.penaltyLog() .build(), ) - Looper.getMainLooper().setMessageLogging(LogMonitor()) - ChoreographerHelper.start() + // Looper.getMainLooper().setMessageLogging(LogMonitor()) + // ChoreographerHelper.start() // Enable recomposition tracking ONLY in debug builds ComposeStabilityAnalyzer.setEnabled(BuildConfig.DEBUG) From b65546487d3fcbe556daff6c9eb7f61dd1d1c1e1 Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Tue, 6 Jan 2026 18:57:56 -0500 Subject: [PATCH 62/63] Adjusts tests to be more flexible when reading NIPs from NIP-11 --- .../quartz/nip11RelayInfo/Nip11RelayInformationTest.kt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip11RelayInfo/Nip11RelayInformationTest.kt b/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip11RelayInfo/Nip11RelayInformationTest.kt index 75e267810..358474f3f 100644 --- a/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip11RelayInfo/Nip11RelayInformationTest.kt +++ b/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip11RelayInfo/Nip11RelayInformationTest.kt @@ -132,7 +132,7 @@ class Nip11RelayInformationTest { assertNotNull(info) assertEquals("test relay", info.name) // Should skip invalid elements and keep only valid integers - assertEquals(listOf("1", "3", "11"), info.supported_nips) + assertEquals(listOf("1", "invalid", "3", "4.5", "true", "11"), info.supported_nips) } @Test @@ -144,7 +144,7 @@ class Nip11RelayInformationTest { assertNotNull(info) assertEquals("test relay", info.name) // All elements invalid, should result in empty list - assertEquals(emptyList(), info.supported_nips) + assertEquals(listOf("one", "two", "three"), info.supported_nips) } @Test @@ -156,7 +156,7 @@ class Nip11RelayInformationTest { assertNotNull(info) assertEquals("test relay", info.name) // Cannot parse float as integer, should be null - assertNull(info.supported_nips) + assertEquals(listOf("1.5"), info.supported_nips) } @Test @@ -168,7 +168,7 @@ class Nip11RelayInformationTest { assertNotNull(info) assertEquals("test relay", info.name) // Cannot parse boolean as integer, should be null - assertNull(info.supported_nips) + assertEquals(listOf("true"), info.supported_nips) } @Test From deb5da48666451f9a261734833859548f37a8c8b Mon Sep 17 00:00:00 2001 From: Crowdin Bot Date: Wed, 7 Jan 2026 00:00:42 +0000 Subject: [PATCH 63/63] New Crowdin translations by GitHub Action --- amethyst/src/main/res/values-pl-rPL/strings.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/amethyst/src/main/res/values-pl-rPL/strings.xml b/amethyst/src/main/res/values-pl-rPL/strings.xml index 11b8200fe..95a8ed79b 100644 --- a/amethyst/src/main/res/values-pl-rPL/strings.xml +++ b/amethyst/src/main/res/values-pl-rPL/strings.xml @@ -357,6 +357,8 @@ Zablokuj Ręczny podział zapów Zakładki + Domyślne zakładki + Twoje domyślne zakładki obsługiwane przez wielu klientów Projekty Prywatne Zakładki Publiczne zakładki