PacketDao

interface PacketDao(source)

Types

Link copied to clipboard
object Companion

Functions

Link copied to clipboard
open suspend fun applyOutgoingQueueStatus(packet: MeshPacket, status: MessageStatus): Packet?

Resolves and conditionally applies a queue-stage status without racing a terminal ACK/NAK update.

Link copied to clipboard
open suspend fun applyOutgoingReactionQueueStatus(packetId: Int, status: MessageStatus): ReactionEntity?

Reaction equivalent of applyOutgoingQueueStatus, restricted to one unambiguous outgoing row.

Link copied to clipboard
open suspend fun applySFPPStatus(packetId: Int, from: Int, to: Int, hash: ByteString, status: MessageStatus, rxTime: Long, myNodeNum: Int?)

Atomically applies an SFPP delivery-status transition to every packet and reaction matching packetId + address (from/to). Preserves the no-downgrade invariant: an item already SFPP_CONFIRMED is not regressed to SFPP_ROUTING. All updates land in one transaction so a packet and its reactions cannot end up in inconsistent delivery states.

Link copied to clipboard
open suspend fun applySFPPStatusByHash(hash: ByteString, status: MessageStatus, rxTime: Long)

Atomically applies an SFPP delivery-status transition to the single packet and single reaction matching hash (8-byte prefix). Same no-downgrade invariant as applySFPPStatus. Both updates land in one transaction.

Link copied to clipboard
open suspend fun backfillMessageTexts(): Int

Populates Packet.messageText for historical text packets that predate the FTS5 schema (v39) so they become searchable. The text is decoded in Kotlin from each packet's DataPacket.text; it cannot be read with a SQL json_extract(data, '$.text') because DataPacket.text is a computed property that is never serialized into the stored JSON (the payload is persisted as bytes). Returns the number of rows updated; the caller rebuilds the FTS index via rebuildFtsIndex when this is greater than zero.

Link copied to clipboard
open suspend fun claimQueuedPacket(myNodeNum: Int, uuid: Long): Packet?

Atomically claims one stable packet row for sending. A returned QUEUED packet means this call performed the QUEUED -> ENROUTE transition and owns the send; any other returned status means another path already handled it.

Link copied to clipboard
open suspend fun claimQueuedPacketByPacketIdIfUnique(packetId: Int): Packet?

Legacy claim used only by pre-upgrade WorkManager jobs whose mesh packet ID still resolves to one row.

Link copied to clipboard
abstract suspend fun clearAllUnreadCounts()
Link copied to clipboard
abstract suspend fun clearUnreadCount(contact: String, timestamp: Long)
Link copied to clipboard
abstract suspend fun countPacketsNeedingBackfill(): Int
Link copied to clipboard
abstract suspend fun delete(uuid: Long)
open suspend fun delete(packet: Packet)
Link copied to clipboard
open suspend fun deleteAll()
Link copied to clipboard
abstract suspend fun deleteAllContactSettings()
Link copied to clipboard
abstract suspend fun deleteAllPackets()
Link copied to clipboard
abstract suspend fun deleteAllReactions()
Link copied to clipboard
abstract suspend fun deleteContacts(contactList: List<String>)
Link copied to clipboard
open suspend fun deleteMessages(uuidList: List<Long>)
Link copied to clipboard
open suspend fun deleteMessagesAtomic(uuidList: List<Long>)

Atomically deletes all messages (and their reactions) for the given uuidList, chunking internally to stay under SQLite's bind-parameter limit. The entire batch is all-or-nothing: a failure rolls back every chunk.

Link copied to clipboard
abstract suspend fun deletePackets(uuidList: List<Long>)
Link copied to clipboard
abstract suspend fun deleteReactions(packetIds: List<Int>)
Link copied to clipboard
open suspend fun deleteWaypoint(id: Int)
Link copied to clipboard
abstract suspend fun findDataPacket(data: DataPacket): Packet?
Link copied to clipboard
abstract suspend fun findPacketBySfppHash(hash: ByteString): Packet?
Link copied to clipboard
abstract suspend fun findPacketsWithId(packetId: Int): List<Packet>
Link copied to clipboard
abstract suspend fun findReactionBySfppHash(hash: ByteString): ReactionEntity?
Link copied to clipboard
abstract suspend fun findReactionsWithId(packetId: Int): List<ReactionEntity>
Link copied to clipboard
Link copied to clipboard
abstract suspend fun getAllDataPackets(): List<DataPacket>
Link copied to clipboard
abstract fun getAllPackets(portNum: Int): Flow<List<Packet>>
Link copied to clipboard
abstract suspend fun getAllPacketsSnapshot(): List<Packet>
Link copied to clipboard
abstract suspend fun getAllPersistedPackets(): List<Packet>
Link copied to clipboard
Link copied to clipboard
abstract suspend fun getAllUserPacketsForMigration(): List<Packet>
Link copied to clipboard
abstract suspend fun getAllWaypoints(): List<Packet>
Link copied to clipboard
abstract suspend fun getContactFilteringDisabled(contact: String): Boolean?
Link copied to clipboard
abstract fun getContactKeys(): Flow<Map<String, Packet>>
Link copied to clipboard
Link copied to clipboard
abstract suspend fun getContactSettings(contact: String): ContactSettings?
Link copied to clipboard
abstract suspend fun getDataPackets(): List<DataPacket>
Link copied to clipboard
abstract suspend fun getFilteredCount(contact: String): Int
Link copied to clipboard
abstract fun getFilteredCountFlow(contact: String): Flow<Int>
Link copied to clipboard
abstract fun getFirstUnreadMessageUuid(contact: String): Flow<Long?>
Link copied to clipboard
abstract suspend fun getMessageCount(contact: String): Int
Link copied to clipboard
abstract fun getMessagesFrom(contact: String): Flow<List<PacketEntity>>
abstract fun getMessagesFrom(contact: String, includeFiltered: Boolean): Flow<List<PacketEntity>>
abstract fun getMessagesFrom(contact: String, limit: Int): Flow<List<PacketEntity>>
Link copied to clipboard
abstract fun getMessagesFromPaged(contact: String, includeFiltered: Boolean): PagingSource<Int, PacketEntity>
Link copied to clipboard
abstract suspend fun getPacketById(requestId: Int): Packet?
Link copied to clipboard
abstract suspend fun getPacketByPacketId(packetId: Int): PacketEntity?
Link copied to clipboard
abstract suspend fun getPacketByPersistedId(myNodeNum: Int, uuid: Long): Packet?
Link copied to clipboard
abstract suspend fun getPacketIdsFrom(uuidList: List<Long>): List<Int>
Link copied to clipboard
abstract suspend fun getPacketsByPacketIdAndContact(packetId: Int, contactKey: String): List<PacketEntity>
Link copied to clipboard
abstract suspend fun getPacketsByPacketIds(packetIds: List<Int>): List<PacketEntity>
Link copied to clipboard
abstract suspend fun getPacketsByPacketIdsAndContact(packetIds: List<Int>, contactKey: String): List<PacketEntity>
Link copied to clipboard
abstract suspend fun getPacketsNeedingBackfill(): List<Packet>
Link copied to clipboard
abstract suspend fun getReactionByPacketId(packetId: Int): ReactionEntity?
Link copied to clipboard
abstract suspend fun getReactionsByStatus(status: MessageStatus): List<ReactionEntity>
Link copied to clipboard
abstract suspend fun getUnreadCount(contact: String): Int
Link copied to clipboard
abstract fun getUnreadCountFlow(contact: String): Flow<Int>
Link copied to clipboard
abstract fun getUnreadCountTotal(): Flow<Int>
Link copied to clipboard
abstract fun hasUnreadMessages(contact: String): Flow<Boolean>
Link copied to clipboard
abstract suspend fun insert(packet: Packet)
abstract suspend fun insert(reaction: ReactionEntity)
Link copied to clipboard
abstract suspend fun insertAndGetId(packet: Packet): Long

Inserts a new packet row and returns its auto-generated stable database UUID.

Link copied to clipboard
abstract suspend fun insertContactSettingsIgnore(contacts: List<ContactSettings>)
Link copied to clipboard
abstract suspend fun insertPacketForMerge(packet: Packet)

Insert a packet copied from another DB. Pass uuid = 0 so a fresh auto-generated id is assigned.

Link copied to clipboard
abstract suspend fun insertReactionsIgnore(reactions: List<ReactionEntity>)
Link copied to clipboard
open suspend fun migrateChannelsByPSK(oldSettings: List<ChannelSettings>, newSettings: List<ChannelSettings>)

One-time migration: Remap all message DataPacket.channel indices to new mapping using PSK after a channel reorder. For each Packet (with port_num = 1), finds the old PSK then sets the channel index to the matching newSettings index. Skips if PSKs do not match or are missing.

Link copied to clipboard
abstract suspend fun rebuildFtsIndex()
Link copied to clipboard
open suspend fun resolveOutgoingPacket(packet: MeshPacket): Packet?

Resolves only an unambiguous row matching the identity available on an outgoing protobuf packet. Mesh packet IDs are sender-scoped, so ID-only lookup can select an inbound packet or an unrelated command with the same ID.

Link copied to clipboard
open suspend fun rollbackEnroutePacket(myNodeNum: Int, uuid: Long): Boolean

Rolls back a failed send only while the exact claimed row is still ENROUTE, preserving any racing ACK update.

Link copied to clipboard
abstract suspend fun searchMessages(query: String): List<Packet>
Link copied to clipboard
abstract suspend fun searchMessagesInConversation(query: String, contactKey: String): List<Packet>
Link copied to clipboard
open suspend fun setContactFilteringDisabled(contact: String, disabled: Boolean)
Link copied to clipboard
open suspend fun setMuteUntil(contacts: List<String>, until: Long)
Link copied to clipboard
abstract suspend fun setShowTranslated(uuid: Long, show: Boolean)
Link copied to clipboard
abstract suspend fun setTranslation(uuid: Long, translatedText: String)

Persists an on-device translation and switches the message to display it in one write.

Link copied to clipboard
open suspend fun timeOutEnroutePacket(myNodeNum: Int, uuid: Long, routingError: Int): Boolean

Stamps routingError on a sent packet only while it is still MessageStatus.ENROUTE. The read and the write share one transaction so an ACK/NAK that resolves the packet concurrently is never overwritten by a send-ack timeout that sampled the row before it landed.

Link copied to clipboard
open suspend fun timeOutEnrouteReaction(myNodeNum: Int, replyId: Int, userId: String, emoji: String, routingError: Int): Boolean

Atomically stamps routingError on a sent reaction only while it is still MessageStatus.ENROUTE.

Link copied to clipboard
abstract suspend fun update(packet: Packet)
abstract suspend fun update(reaction: ReactionEntity)
Link copied to clipboard
abstract suspend fun updateEnrouteReactionStatus(myNodeNum: Int, replyId: Int, userId: String, emoji: String, routingError: Int, enrouteStatus: MessageStatus, failedStatus: MessageStatus): Int
Link copied to clipboard
abstract suspend fun updateFilteredBySender(senderIdPattern: String, filtered: Boolean)
Link copied to clipboard
open suspend fun updateLastReadMessage(contact: String, messageUuid: Long, lastReadTimestamp: Long)

Atomically updates the last-read message pointer for contact, preserving the monotonic-timestamp guard: if lastReadTimestamp is not newer than the stored value, the method is a no-op. Creates the contact-settings row if absent. Uses INSERT OR IGNORE + conditional UPDATE instead of a read-then-@Upsert so the existing row's unrelated columns (muteUntil, filteringDisabled) are preserved without a Kotlin-side read-modify-write.

Link copied to clipboard
abstract suspend fun updateLastReadMessageIfNewer(contact: String, messageUuid: Long, lastReadTimestamp: Long): Int

Conditional UPDATE that only writes newer timestamps. Callers must ensure the contact-settings row exists (e.g. via insertContactSettingsIgnore) before calling this inside the same transaction.

Link copied to clipboard
open suspend fun updateMessageId(data: DataPacket, id: Int)
Link copied to clipboard
open suspend fun updateMessageStatus(data: DataPacket, m: MessageStatus)
Link copied to clipboard
open suspend fun updateMessageStatusByPersistedId(myNodeNum: Int, uuid: Long, status: MessageStatus)
Link copied to clipboard
abstract suspend fun updateMessageText(uuid: Long, text: String)
Link copied to clipboard
abstract suspend fun updateMuteUntil(contactKeys: List<String>, muteUntil: Long)
Link copied to clipboard
open suspend fun updateOutgoingMessageStatus(packet: MeshPacket, status: MessageStatus): Packet?

Updates the unique outgoing row, preferring the only candidate already at status when duplicates exist.

Link copied to clipboard
open suspend fun updatePacketByKey(data: DataPacket, routingError: Int)

Atomically finds a packet by identity key (id + from + to) and updates its data, optionally stamping routingError when it is non-negative. Mirrors the existing updateMessageStatus / updateMessageId pattern.

Link copied to clipboard
open suspend fun updateReactionByKey(replacement: ReactionEntity)

Atomically finds reactions by replacement's packetId + userId + emoji and updates every ownership-scoped copy, borrowing myNodeNum from each existing row. No-op if no match is found.

Link copied to clipboard
abstract suspend fun upsertContactSettings(contacts: List<ContactSettings>)