feat: mantra compiles for the jvm

Phase 4. Declares jvm(), implements all 16 expects, and bumps the
submodule to the fork branch carrying phases 1-3.
:composeApp:compileKotlinJvm is green.

**The actuals were the small half. Room was the blocker.** The first jvm
compile failed with 58 copies of "Only suspend functions are allowed in
DAOs declared in source sets targeting non-Android platforms". Room
permits blocking query methods on android and nowhere else, so every @Dao
function that was neither suspend nor Flow-returning had to change --
58 of them across 24 files. KSP reports these in alphabetical batches, so
the count shrinks in stages and looks bottomless; scanning the dao package
directly for abstract funs with no suspend and no Flow return finds them
all at once.

It stops there, which is the only reason this is a 58-line change rather
than a refactor. Every one of the 15 call sites outside the dao package
was already inside a suspend function -- the repositories were written
that way throughout -- so nothing needed rewriting. One private helper,
DatabaseNostrRepository.matchNegentropicNostrEvents, had to become
suspend, and its single caller was already suspend, so the cascade
terminated immediately. Zero call-site edits.

**The cost lands on android, not on the jvm.** A blocking DAO method runs
on its caller's thread; a suspend one is dispatched to the query coroutine
context, which getRoomDatabase sets to Dispatchers.IO. That is the better
behaviour -- it is what stops a query running on the main thread -- but it
is a real change to the shipping platform, made for a target that does not
run yet. Hence the unit tests below rather than a compile alone.

**BusinessManager was not an expect**, so nothing warned about it. It is
now ported to the fork's jvmMain (05ce7eb); Phoenix.jvm.kt and
NavigationViewModel.jvm.kt are otherwise the ios actuals with one changed
import, since those files use no ios API.

**schedulePlatformLogic schedules nothing, and logs that it does not.**
Android starts two WorkManager jobs here, one of which is ChannelsWatcher
-- it wakes periodically to notice a channel force-closed while the app
was shut. A desktop application has no process once its window closes, so
there is nothing to wake, and running the watcher in-process would be
strictly worse than not running it: it would only fire while the app was
already open and watching. The exposure is real and belongs in release
notes rather than a comment -- a desktop wallet left closed past a
force-close deadline does not notice.

Smaller calls. PlatformContext carries an application directory, since
there is no Context to read one from, and PlatformDatabaseBuilder puts
aux.db under it rather than in java.io.tmpdir, which is what the abandoned
Aux implementation did behind a TODO and which most systems clear on
reboot. themeColorScheme ignores dynamicColor, which means Material You
and has no desktop counterpart. AppVersion reads the jar manifest that
compose.desktop writes, falling back when running from a class directory.

Verified: :composeApp:compileKotlinJvm green,
:composeApp:compileDebugKotlinAndroid green, and
:composeApp:testDebugUnitTest 52 passing -- the one that matters, since
this commit changes shared code every android query path goes through.

Not verified: nothing has run. No jvm entry point exists yet, so the
database has never been opened on this platform and no business has been
started. That is phase 5, which also has to unlock JvmKeyStore before the
wallet starts -- a passphrase prompt, not just a window.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Kgothatso Ngako
2026-09-06 01:23:42 +02:00
parent 670f87a609
commit bf4041a5b2
35 changed files with 437 additions and 66 deletions

View File

@@ -8,7 +8,7 @@ import kotlinx.coroutines.flow.Flow
@Dao
interface BroadcastNostrEventReceiptDao {
@Query("SELECT * FROM BroadcastNostrEventReceipt")
fun getAllBroadcastNostrEventReceipts(): List<press.mantra.compose.database.model.BroadcastNostrEventReceipt>
suspend fun getAllBroadcastNostrEventReceipts(): List<press.mantra.compose.database.model.BroadcastNostrEventReceipt>
@Query("SELECT * FROM BroadcastNostrEventReceipt WHERE id = :id")
fun getBroadcastNostrEventReceiptById(id: Long): Flow<press.mantra.compose.database.model.BroadcastNostrEventReceipt?>

View File

@@ -12,10 +12,10 @@ import kotlin.time.Instant
@Dao
interface BroadcastNostrEventRequestDao {
@Query("SELECT * FROM BroadcastNostrEventRequest")
fun getAllBroadcastNostrEventRequests(): List<BroadcastNostrEventRequest>
suspend fun getAllBroadcastNostrEventRequests(): List<BroadcastNostrEventRequest>
@Query("SELECT * FROM BroadcastNostrEventRequest WHERE nostrEventId = :nostrEventId ORDER BY createdAt ASC")
fun getFirstBroadcastNostrEventRequestByNostrEventId(nostrEventId: String): BroadcastNostrEventRequest?
suspend fun getFirstBroadcastNostrEventRequestByNostrEventId(nostrEventId: String): BroadcastNostrEventRequest?
// See NegentropySynchronizeRequestDao: the old `createdAt > :createdAt` bound a
// once-evaluated `Clock.System.now()` for the life of the Flow. Because Instants are

View File

@@ -16,19 +16,19 @@ interface ChatMessageDao {
@Transaction
@Query("SELECT * FROM ChatMessage WHERE chatRoomId = :chatRoomId ORDER BY createdAt DESC")
fun getChatMessagesByChatRoomId(chatRoomId: String): List<press.mantra.compose.database.model.intermdiate.LocalChatMessage>
suspend fun getChatMessagesByChatRoomId(chatRoomId: String): List<press.mantra.compose.database.model.intermdiate.LocalChatMessage>
@Query("SELECT * FROM ChatMessage WHERE giftWrapPayloadId = :giftWrapPayloadId ORDER BY createdAt DESC")
fun getChatMessagesByGiftWrapPayloadId(giftWrapPayloadId: HexKey): ChatMessage?
suspend fun getChatMessagesByGiftWrapPayloadId(giftWrapPayloadId: HexKey): ChatMessage?
@Query("SELECT * FROM ChatMessage WHERE marmotInnerEventId = :marmotInnerEventId ORDER BY createdAt DESC")
fun getChatMessagesByMarmotInnerEventId(marmotInnerEventId: HexKey): ChatMessage?
suspend fun getChatMessagesByMarmotInnerEventId(marmotInnerEventId: HexKey): ChatMessage?
@Query("SELECT * FROM ChatMessage WHERE marmotGroupEventId = :marmotGroupEventId ORDER BY createdAt DESC")
fun getChatMessagesByMarmotGroupEventId(marmotGroupEventId: HexKey): ChatMessage?
suspend fun getChatMessagesByMarmotGroupEventId(marmotGroupEventId: HexKey): ChatMessage?
@Query("SELECT COUNT(*) FROM ChatMessage WHERE chatRoomId = :chatRoomId AND senderPublicKey = :senderPublicKey")
fun countChatMessagesBySenderPublicKey(chatRoomId: HexKey, senderPublicKey: HexKey): Int
suspend fun countChatMessagesBySenderPublicKey(chatRoomId: HexKey, senderPublicKey: HexKey): Int
@Upsert
suspend fun upsert(chatMessage: press.mantra.compose.database.model.ChatMessage): Long

View File

@@ -13,11 +13,11 @@ import kotlinx.coroutines.flow.Flow
interface ChatRoomDao {
@Transaction
@Query("SELECT * FROM ChatRoom WHERE id = :id AND deletedAt IS NULL")
fun findChatRoomById(id: String): LocalChatRoom?
suspend fun findChatRoomById(id: String): LocalChatRoom?
@Transaction
@Query("SELECT * FROM ChatRoom WHERE userPublicKey = :userPublicKey AND deletedAt IS NULL")
fun getChatRoomListByUserPublicKey(userPublicKey: String): List<LocalChatRoom>
suspend fun getChatRoomListByUserPublicKey(userPublicKey: String): List<LocalChatRoom>
@Transaction
@Query("SELECT * FROM ChatRoom WHERE userPublicKey = :userPublicKey AND deletedAt IS NULL")

View File

@@ -11,7 +11,7 @@ import kotlinx.coroutines.flow.Flow
@Dao
interface ConnectionDao {
@Query("SELECT * FROM Connection LIMIT :limit")
fun getAllConnections(limit: Int = 21): List<press.mantra.compose.database.model.Connection>
suspend fun getAllConnections(limit: Int = 21): List<press.mantra.compose.database.model.Connection>
@Query("SELECT * FROM Connection WHERE (sourcePublicKey = :alicePublicKey AND destinationPublicKey = :bobPublicKey) OR (sourcePublicKey = :bobPublicKey AND destinationPublicKey = :alicePublicKey)")

View File

@@ -7,7 +7,7 @@ import androidx.room3.Upsert
@Dao
interface GiftWrapMessageDao {
@Query("SELECT * FROM GiftWrapMessage")
fun getAllGiftWrapMessages(): List<press.mantra.compose.database.model.GiftWrapMessage>
suspend fun getAllGiftWrapMessages(): List<press.mantra.compose.database.model.GiftWrapMessage>
@Upsert
suspend fun upsert(giftWrapMessage: press.mantra.compose.database.model.GiftWrapMessage)

View File

@@ -11,7 +11,7 @@ import kotlinx.coroutines.flow.Flow
@Dao
interface GiftWrapPayloadDao {
@Query("SELECT * FROM GiftWrapPayload")
fun getAllGiftWrapUnsigned(): List<GiftWrapPayload>
suspend fun getAllGiftWrapUnsigned(): List<GiftWrapPayload>
@Query("SELECT * FROM GiftWrapPayload WHERE publicKey = :publicKey AND giftWrapSealId IS NULL")
fun observeUnsealedGiftWrapPayloads(publicKey: String): Flow<GiftWrapPayload?>

View File

@@ -7,7 +7,7 @@ import androidx.room3.Upsert
@Dao
interface GiftWrapSealDao {
@Query("SELECT * FROM GiftWrapSeal")
fun getAllGiftWrapSeals(): List<press.mantra.compose.database.model.GiftWrapSeal>
suspend fun getAllGiftWrapSeals(): List<press.mantra.compose.database.model.GiftWrapSeal>
@Upsert
suspend fun upsert(giftWrapSeal: press.mantra.compose.database.model.GiftWrapSeal)

View File

@@ -8,10 +8,10 @@ import androidx.room3.Upsert
@Dao
interface InReplyToRelationDao {
@Query("SELECT * FROM InReplyToRelation WHERE replyingNostrEventId = :replyingNostrEventId")
fun getRepostByReplyingNostrEventId(replyingNostrEventId: String): press.mantra.compose.database.model.InReplyToRelation?
suspend fun getRepostByReplyingNostrEventId(replyingNostrEventId: String): press.mantra.compose.database.model.InReplyToRelation?
@Query("SELECT * FROM InReplyToRelation WHERE inReplyToNostrEventId = :inReplyToNostrEventId")
fun getRepostByInReplyToNostrEventId(inReplyToNostrEventId: String): press.mantra.compose.database.model.InReplyToRelation?
suspend fun getRepostByInReplyToNostrEventId(inReplyToNostrEventId: String): press.mantra.compose.database.model.InReplyToRelation?
@Insert
suspend fun insert(inReplyToRelation: press.mantra.compose.database.model.InReplyToRelation)

View File

@@ -16,10 +16,10 @@ interface MarmotKeyPackageBundleDao {
fun observeAllMarmotKeyPackageBundles(publicKey: HexKey): Flow<List<MarmotKeyPackageBundle>>
@Query("SELECT * FROM MarmotKeyPackageBundle WHERE publicKey = :publicKey ORDER BY createdAt DESC")
fun getAllMarmotKeyPackageBundles(publicKey: HexKey): List<MarmotKeyPackageBundle>
suspend fun getAllMarmotKeyPackageBundles(publicKey: HexKey): List<MarmotKeyPackageBundle>
@Query("SELECT * FROM MarmotKeyPackageBundle WHERE id = :id ORDER BY createdAt DESC")
fun getMarmotKeyPackageBundleById(id: String): MarmotKeyPackageBundle?
suspend fun getMarmotKeyPackageBundleById(id: String): MarmotKeyPackageBundle?
@Upsert
suspend fun upsert(marmotKeyPackageBundle: MarmotKeyPackageBundle)

View File

@@ -18,7 +18,7 @@ interface NegentropySynchronizeRequestDao {
fun observeNegentropySynchronizeRequestByPurposeAndStatusCount(purpose: String, status: List<String>): Flow<Int>
@Upsert
fun upsert(negentropySynchronizeRequest: NegentropySynchronizeRequest)
suspend fun upsert(negentropySynchronizeRequest: NegentropySynchronizeRequest)
/**
* Upsert rather than insert-or-ignore. `computeId` buckets by minute, so an identical
@@ -28,5 +28,5 @@ interface NegentropySynchronizeRequestDao {
* hit the network, while still collapsing duplicates into a single row.
*/
@Upsert
fun insert(negentropySynchronizeRequests: List<NegentropySynchronizeRequest>)
suspend fun insert(negentropySynchronizeRequests: List<NegentropySynchronizeRequest>)
}

View File

@@ -6,5 +6,5 @@ import androidx.room3.Upsert
@Dao
interface NegentropySynchronizeResultDao {
@Upsert
fun upsert(negentropySynchronizeResult: press.mantra.compose.database.model.NegentropySynchronizeResult)
suspend fun upsert(negentropySynchronizeResult: press.mantra.compose.database.model.NegentropySynchronizeResult)
}

View File

@@ -73,13 +73,13 @@ interface NostrEventDao {
* constraints they had no parameter for.
*/
@RawQuery
fun getNostrEventsMatchingFilter(
suspend fun getNostrEventsMatchingFilter(
query: RoomRawQuery
): List<NostrEvent>
@Transaction
@Query("SELECT * FROM NostrEvent WHERE kind in (:kinds) AND createdAt > :since ORDER BY createdAt ASC LIMIT :limit")
fun getNostrEvents(
suspend fun getNostrEvents(
kinds: Array<Kind>,
since: Instant,
limit: Int
@@ -87,7 +87,7 @@ interface NostrEventDao {
@Transaction
@Query("SELECT * FROM NostrEvent WHERE content LIKE '%' || :search || '%' AND kind in (:kinds) AND createdAt > :since ORDER BY createdAt ASC LIMIT :limit")
fun getFilteredNostrEvents(
suspend fun getFilteredNostrEvents(
kinds: Array<Kind>,
search: String,
since: Instant,
@@ -96,7 +96,7 @@ interface NostrEventDao {
@Transaction
@Query("SELECT * FROM NostrEvent WHERE kind in (:kinds) AND id in (:ids) AND createdAt > :since ORDER BY createdAt ASC LIMIT :limit")
fun getFilteredNostrEvents(
suspend fun getFilteredNostrEvents(
kinds: Array<Kind>,
ids: Array<HexKey>,
since: Instant,
@@ -105,7 +105,7 @@ interface NostrEventDao {
@Transaction
@Query("SELECT * FROM NostrEvent WHERE id in (:ids) AND createdAt > :since ORDER BY createdAt ASC LIMIT :limit")
fun getNostrEventsByIds(
suspend fun getNostrEventsByIds(
ids: Array<HexKey>,
since: Instant,
limit: Int
@@ -114,7 +114,7 @@ interface NostrEventDao {
@Transaction
@Query("SELECT * FROM NostrEvent WHERE kind = ${GroupEvent.KIND} AND createdAt > :since ORDER BY createdAt ASC LIMIT :limit")
fun getMLSGroupEvents(
suspend fun getMLSGroupEvents(
since: Instant,
limit: Int
): List<NostrEvent>
@@ -135,7 +135,7 @@ interface NostrEventDao {
"AND (expiresAt IS NULL OR expiresAt > :now) " +
"ORDER BY createdAt DESC LIMIT :limit"
)
fun getMarmotGroupEvents(
suspend fun getMarmotGroupEvents(
chatRoomIds: Array<HexKey>,
since: Instant,
until: Instant,
@@ -145,7 +145,7 @@ interface NostrEventDao {
@Transaction
@Query("SELECT * FROM NostrEvent WHERE kind in (:kinds) AND pubKey in (:authors) AND createdAt > :since ORDER BY createdAt ASC LIMIT :limit")
fun getAuthoredNostrEvents(
suspend fun getAuthoredNostrEvents(
kinds: Array<Kind>,
authors: Array<HexKey>,
since: Instant,
@@ -154,7 +154,7 @@ interface NostrEventDao {
@Transaction
@Query("SELECT * FROM NostrEvent WHERE tags LIKE '%' || :publicKey || '%' AND kind in (:kinds) AND createdAt > :since ORDER BY createdAt ASC LIMIT :limit")
fun getPublicKeyMentionedNostrEvents(
suspend fun getPublicKeyMentionedNostrEvents(
kinds: Array<Kind>,
publicKey: HexKey,
since: Instant,
@@ -163,7 +163,7 @@ interface NostrEventDao {
@Transaction
@Query("SELECT * FROM NostrEvent WHERE tags LIKE '%' || :eventId || '%reply%' AND kind in (:kinds) AND createdAt > :since ORDER BY createdAt ASC LIMIT :limit")
fun getNostrEventReplies(
suspend fun getNostrEventReplies(
kinds: Array<Kind>,
eventId: HexKey,
since: Instant,
@@ -171,17 +171,17 @@ interface NostrEventDao {
): List<NostrEvent>
@Query("SELECT * FROM NostrEvent WHERE kind in (:kinds) ORDER BY savedAt DESC")
fun getAllNostrEvents(kinds: Array<Kind>): List<NostrEvent>
suspend fun getAllNostrEvents(kinds: Array<Kind>): List<NostrEvent>
@Transaction
@Query("SELECT * FROM NostrEvent WHERE id = :id")
fun observeNostrEventById(id: String): Flow<press.mantra.compose.database.model.intermdiate.LocalNostrEvent?>
@Query("SELECT * FROM NostrEvent WHERE id = :id")
fun getNostrEventById(id: String): NostrEvent?
suspend fun getNostrEventById(id: String): NostrEvent?
@Query("SELECT * FROM NostrEvent WHERE pubKey = :publicKey AND kind = :kind ORDER BY createdAt DESC")
fun getNostrEventByPublicKeyAndKind(publicKey: HexKey, kind: Kind): NostrEvent?
suspend fun getNostrEventByPublicKeyAndKind(publicKey: HexKey, kind: Kind): NostrEvent?
@Upsert
suspend fun upsert(nostrEvent: NostrEvent)

View File

@@ -9,10 +9,10 @@ import press.mantra.compose.database.model.Participant
@Dao
interface ParticipantDao {
@Query("SELECT * FROM Participant WHERE participantPublicKey = :participantPublicKey")
fun findParticipantByPublicKey(participantPublicKey: String): List<Participant>
suspend fun findParticipantByPublicKey(participantPublicKey: String): List<Participant>
@Query("SELECT * FROM Participant WHERE chatRoomId = :chatRoomId")
fun findParticipantsByChatRoomId(chatRoomId: String): List<Participant>
suspend fun findParticipantsByChatRoomId(chatRoomId: String): List<Participant>
@Upsert
suspend fun upsert(participants: List<Participant>)

View File

@@ -8,10 +8,10 @@ import androidx.room3.Upsert
@Dao
interface PostDao {
@Query("SELECT * FROM Post")
fun getAllPosts(): List<press.mantra.compose.database.model.intermdiate.LocalPost>
suspend fun getAllPosts(): List<press.mantra.compose.database.model.intermdiate.LocalPost>
@Query("SELECT * FROM Post WHERE id = :id")
fun getPostById(id: String): press.mantra.compose.database.model.Post?
suspend fun getPostById(id: String): press.mantra.compose.database.model.Post?
@Insert
suspend fun insert(post: press.mantra.compose.database.model.Post)

View File

@@ -13,26 +13,26 @@ import kotlin.time.Instant
@Dao
interface ProfileDao {
@Query("SELECT * FROM Profile WHERE createdAt > :createdAt LIMIT :limit")
fun getAllProfiles(limit: Int = 21, createdAt: Instant = GENESIS_AT): List<Profile>
suspend fun getAllProfiles(limit: Int = 21, createdAt: Instant = GENESIS_AT): List<Profile>
@Query("SELECT * FROM Profile WHERE publicKey NOT IN (:excludedPublicKeys) AND createdAt > :createdAt LIMIT :limit")
fun getAllProfilesExcludingOnesWithThesePublicKeys(
suspend fun getAllProfilesExcludingOnesWithThesePublicKeys(
excludedPublicKeys: Array<HexKey>,
limit: Int = 21, createdAt: Instant = GENESIS_AT
): List<Profile>
@Query("SELECT * FROM NostrEvent WHERE kind = 0 AND content LIKE '%' || :searchTerm || '%' LIMIT :limit")
fun filterProfiles(searchTerm: String, limit: Int = 21): List<press.mantra.compose.database.model.intermdiate.LocalProfile>
suspend fun filterProfiles(searchTerm: String, limit: Int = 21): List<press.mantra.compose.database.model.intermdiate.LocalProfile>
@Query("SELECT * FROM Profile WHERE publicKey = :publicKey")
fun getProfileByPublicKey(publicKey: String): Profile?
suspend fun getProfileByPublicKey(publicKey: String): Profile?
@Query("SELECT * FROM Profile WHERE publicKey = :publicKey")
fun observeProfileByPublicKey(publicKey: String): Flow<Profile?>
@Query("SELECT * FROM Profile WHERE publicKey IN (:publicKeys)")
fun getProfileByPublicKeys(publicKeys: List<String>): List<Profile>
suspend fun getProfileByPublicKeys(publicKeys: List<String>): List<Profile>
@Query("SELECT * FROM NostrEvent WHERE kind = 0 AND pubKey = :publicKey")
fun observeProfileWithFollowersByPublicKey(publicKey: String): Flow<press.mantra.compose.database.model.intermdiate.LocalProfileWithFollowers?>

View File

@@ -8,10 +8,10 @@ import androidx.room3.Upsert
@Dao
interface QuotedRelationDao {
@Query("SELECT * FROM QuotedRelation WHERE quotingNostrEventId = :quotingNostrEventId")
fun getRepostByQuotingNostrEventId(quotingNostrEventId: String): press.mantra.compose.database.model.QuotedRelation?
suspend fun getRepostByQuotingNostrEventId(quotingNostrEventId: String): press.mantra.compose.database.model.QuotedRelation?
@Query("SELECT * FROM QuotedRelation WHERE quotedNostrEventId = :quotedNostrEventId")
fun getRepostByQuotedNostrEventId(quotedNostrEventId: String): press.mantra.compose.database.model.QuotedRelation?
suspend fun getRepostByQuotedNostrEventId(quotedNostrEventId: String): press.mantra.compose.database.model.QuotedRelation?
@Insert
suspend fun insert(quotedRelation: press.mantra.compose.database.model.QuotedRelation)

View File

@@ -8,7 +8,7 @@ import kotlinx.coroutines.flow.Flow
@Dao
interface ReactionDao {
@Query("SELECT * FROM Reaction")
fun getAllReactions(): List<press.mantra.compose.database.model.Reaction>
suspend fun getAllReactions(): List<press.mantra.compose.database.model.Reaction>
@Query("SELECT * FROM Reaction WHERE id = :id")
fun getReactionById(id: String): Flow<press.mantra.compose.database.model.Reaction?>

View File

@@ -12,10 +12,10 @@ interface RecentSearchDao {
fun observeRecentSearchByQuery(query: String): Flow<press.mantra.compose.database.model.RecentSearch?>
@Query("SELECT * FROM RecentSearch ORDER BY createdAt DESC LIMIT :limit ")
fun getAllRecentSearches(limit: Int = 21): List<press.mantra.compose.database.model.RecentSearch>
suspend fun getAllRecentSearches(limit: Int = 21): List<press.mantra.compose.database.model.RecentSearch>
@Delete
fun deleteRecentSearch(recentSearch: press.mantra.compose.database.model.RecentSearch)
suspend fun deleteRecentSearch(recentSearch: press.mantra.compose.database.model.RecentSearch)
@Upsert
suspend fun upsert(recentSearch: press.mantra.compose.database.model.RecentSearch)

View File

@@ -8,7 +8,7 @@ import kotlinx.coroutines.flow.Flow
@Dao
interface RelayDao {
@Query("SELECT * FROM Relay")
fun getAllPosts(): List<press.mantra.compose.database.model.Relay>
suspend fun getAllPosts(): List<press.mantra.compose.database.model.Relay>
@Query("SELECT * FROM Relay WHERE publicKey = :publicKey")
fun observePublicKeyRelays(publicKey: String): Flow<List<press.mantra.compose.database.model.Relay>>

View File

@@ -7,13 +7,13 @@ import androidx.room3.Upsert
@Dao
interface RepostedRelationDao {
@Query("SELECT * FROM RepostedRelation")
fun getAllReposts(): List<press.mantra.compose.database.model.RepostedRelation>
suspend fun getAllReposts(): List<press.mantra.compose.database.model.RepostedRelation>
@Query("SELECT * FROM RepostedRelation WHERE repostingNostrEventId = :repostingNostrEventId")
fun getRepostByRepostingId(repostingNostrEventId: String): press.mantra.compose.database.model.RepostedRelation?
suspend fun getRepostByRepostingId(repostingNostrEventId: String): press.mantra.compose.database.model.RepostedRelation?
@Query("SELECT * FROM RepostedRelation WHERE repostedNostrEventId = :repostedNostrEventId")
fun getRepostByRepostedId(repostedNostrEventId: String): press.mantra.compose.database.model.RepostedRelation?
suspend fun getRepostByRepostedId(repostedNostrEventId: String): press.mantra.compose.database.model.RepostedRelation?
@Upsert
suspend fun upsert(repostedRelation: press.mantra.compose.database.model.RepostedRelation)

View File

@@ -18,8 +18,8 @@ interface SynchronizeNostrEventRequestDao {
fun observeSynchronizeNostrEventRequestByPurposeAndStatusCount(purpose: String, status: List<String>): Flow<Int>
@Upsert
fun upsert(synchronizeNostrEventRequest: press.mantra.compose.database.model.SynchronizeNostrEventRequest)
suspend fun upsert(synchronizeNostrEventRequest: press.mantra.compose.database.model.SynchronizeNostrEventRequest)
@Insert
fun insert(synchronizeNostrEventRequests: List<press.mantra.compose.database.model.SynchronizeNostrEventRequest>)
suspend fun insert(synchronizeNostrEventRequests: List<press.mantra.compose.database.model.SynchronizeNostrEventRequest>)
}

View File

@@ -6,5 +6,5 @@ import androidx.room3.Upsert
@Dao
interface SynchronizeNostrEventResultDao {
@Upsert
fun upsert(synchronizeNostrEventResult: press.mantra.compose.database.model.SynchronizeNostrEventResult)
suspend fun upsert(synchronizeNostrEventResult: press.mantra.compose.database.model.SynchronizeNostrEventResult)
}

View File

@@ -12,10 +12,10 @@ import press.mantra.compose.database.model.UnsignedNostrEvent
@Dao
interface UnsignedNostrEventDao {
@Query("SELECT * FROM UnsignedNostrEvent")
fun getAUnsignedNostrEvents(): List<UnsignedNostrEvent>
suspend fun getAUnsignedNostrEvents(): List<UnsignedNostrEvent>
@Query("SELECT * FROM UnsignedNostrEvent") // TODO: where nostrEvent.unsignedNostrEventId is 0
fun getAllUnprocessedUnsignedNostrEvents(): List<UnsignedNostrEvent>
suspend fun getAllUnprocessedUnsignedNostrEvents(): List<UnsignedNostrEvent>
@Query("SELECT * FROM UnsignedNostrEvent WHERE id = :id")
fun getUnsignedNostrEventById(id: Long): Flow<UnsignedNostrEvent?>
@@ -32,7 +32,7 @@ interface UnsignedNostrEventDao {
@Transaction
@Query("SELECT * FROM UnsignedNostrEvent WHERE kind = 0")
fun getLocalAccounts(): List<LocalAccount>
suspend fun getLocalAccounts(): List<LocalAccount>
@Query("SELECT * FROM UnsignedNostrEvent WHERE pubKey = :publicKey AND signedAt IS NULL ORDER BY kind ASC")
fun observeUnsignedNostrEvents(publicKey: String): Flow<UnsignedNostrEvent?>

View File

@@ -647,7 +647,7 @@ class DatabaseNostrRepository(
.distinctBy { it.id }
}
private fun matchNegentropicNostrEvents(
private suspend fun matchNegentropicNostrEvents(
synchronizationFilter: SynchronizationFilter,
applyLimits: Boolean,
): List<NostrEvent> {